@subwallet/extension-base 1.0.9-0 → 1.0.9-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/background/KoniTypes.d.ts +5 -1
  2. package/background/types.d.ts +2 -1
  3. package/cjs/koni/background/handlers/Extension.js +33 -6
  4. package/cjs/koni/background/handlers/State.js +3 -3
  5. package/cjs/packageInfo.js +1 -1
  6. package/cjs/services/chain-service/constants.js +2 -2
  7. package/cjs/services/chain-service/index.js +1 -1
  8. package/cjs/services/migration-service/scripts/MigrateLedgerAccount.js +42 -0
  9. package/cjs/services/migration-service/scripts/index.js +3 -1
  10. package/cjs/services/transaction-service/index.js +15 -15
  11. package/cjs/signers/web3/QrSigner.js +14 -6
  12. package/cjs/utils/eth/mergeTransactionAndSignature.js +22 -13
  13. package/cjs/utils/eth/parseTransaction/base.js +6 -6
  14. package/cjs/utils/eth/parseTransaction/index.js +4 -5
  15. package/cjs/utils/eth.js +14 -18
  16. package/koni/background/handlers/Extension.js +33 -6
  17. package/koni/background/handlers/State.js +3 -3
  18. package/package.json +12 -8
  19. package/packageInfo.js +1 -1
  20. package/services/chain-service/constants.js +2 -2
  21. package/services/chain-service/index.js +1 -1
  22. package/services/migration-service/scripts/MigrateLedgerAccount.d.ts +4 -0
  23. package/services/migration-service/scripts/MigrateLedgerAccount.js +33 -0
  24. package/services/migration-service/scripts/index.js +3 -1
  25. package/services/transaction-service/index.js +17 -17
  26. package/signers/types.d.ts +1 -1
  27. package/signers/web3/QrSigner.js +14 -5
  28. package/utils/eth/mergeTransactionAndSignature.d.ts +1 -1
  29. package/utils/eth/mergeTransactionAndSignature.js +20 -10
  30. package/utils/eth/parseTransaction/base.js +6 -6
  31. package/utils/eth/parseTransaction/index.js +4 -5
  32. package/utils/eth.d.ts +2 -3
  33. package/utils/eth.js +14 -17
@@ -628,6 +628,7 @@ export interface CreateHardwareAccountItem {
628
628
  genesisHash: string;
629
629
  hardwareType: string;
630
630
  name: string;
631
+ isEthereum: boolean;
631
632
  }
632
633
  export interface RequestAccountCreateHardwareMultiple {
633
634
  accounts: CreateHardwareAccountItem[];
@@ -979,11 +980,14 @@ export interface ResponseParseEvmContractInput {
979
980
  }
980
981
  export interface LedgerNetwork {
981
982
  genesisHash: string;
982
- displayName: string;
983
+ networkName: string;
984
+ accountName: string;
985
+ appName: string;
983
986
  network: string;
984
987
  slug: string;
985
988
  icon: 'substrate' | 'ethereum';
986
989
  isDevMode: boolean;
990
+ isEthereum: boolean;
987
991
  }
988
992
  export interface TransakNetwork {
989
993
  networks: string[];
@@ -27,7 +27,6 @@ export interface AbstractAddressJson extends KeyringPair$Meta {
27
27
  type?: KeypairType;
28
28
  whenCreated?: number;
29
29
  name?: string;
30
- originGenesisHash?: string | null;
31
30
  }
32
31
  export interface AccountJson extends AbstractAddressJson {
33
32
  accountIndex?: number;
@@ -41,6 +40,8 @@ export interface AccountJson extends AbstractAddressJson {
41
40
  isReadOnly?: boolean;
42
41
  parentAddress?: string;
43
42
  suri?: string;
43
+ originGenesisHash?: string | null;
44
+ availableGenesisHashes?: string[];
44
45
  }
45
46
  export interface AddressJson extends AbstractAddressJson {
46
47
  isRecent?: boolean;
@@ -1740,7 +1740,7 @@ class KoniExtension {
1740
1740
  }
1741
1741
  } else {
1742
1742
  const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
1743
- if ((0, _utils._isChainEvmCompatible)(chainInfo)) {
1743
+ if ((0, _utils._isChainEvmCompatible)(chainInfo) && (0, _utils._isTokenTransferredByEvm)(tokenInfo)) {
1744
1744
  const web3 = this.#koniState.chainService.getEvmApi(networkKey);
1745
1745
  const transaction = {
1746
1746
  value: 0,
@@ -1983,6 +1983,7 @@ class KoniExtension {
1983
1983
  if (!accounts.length) {
1984
1984
  throw new Error('No accounts to import');
1985
1985
  }
1986
+ const slugMap = {};
1986
1987
  for (const account of accounts) {
1987
1988
  const {
1988
1989
  accountIndex,
@@ -1990,16 +1991,36 @@ class KoniExtension {
1990
1991
  addressOffset,
1991
1992
  genesisHash,
1992
1993
  hardwareType,
1994
+ isEthereum,
1993
1995
  name
1994
1996
  } = account;
1995
- const key = _uiKeyring.keyring.addHardware(address, hardwareType, {
1997
+ let result;
1998
+ const baseMeta = {
1999
+ name,
2000
+ hardwareType,
1996
2001
  accountIndex,
1997
2002
  addressOffset,
1998
2003
  genesisHash,
1999
- name,
2000
2004
  originGenesisHash: genesisHash
2001
- });
2002
- const result = key.pair;
2005
+ };
2006
+ if (isEthereum) {
2007
+ result = _uiKeyring.keyring.keyring.addFromAddress(address, {
2008
+ ...baseMeta,
2009
+ isExternal: true,
2010
+ isHardware: true
2011
+ }, null, 'ethereum');
2012
+ _uiKeyring.keyring.saveAccount(result);
2013
+ slugMap.ethereum = 'ethereum';
2014
+ } else {
2015
+ result = _uiKeyring.keyring.addHardware(address, hardwareType, {
2016
+ ...baseMeta,
2017
+ availableGenesisHashes: [genesisHash]
2018
+ }).pair;
2019
+ const [slug] = this.#koniState.findNetworkKeyByGenesisHash(genesisHash);
2020
+ if (slug) {
2021
+ slugMap[slug] = slug;
2022
+ }
2023
+ }
2003
2024
  const _address = result.address;
2004
2025
  addresses.push(_address);
2005
2026
  await new Promise(resolve => {
@@ -2027,6 +2048,12 @@ class KoniExtension {
2027
2048
  resolve();
2028
2049
  });
2029
2050
  });
2051
+ if (Object.keys(slugMap).length) {
2052
+ this.enableChains({
2053
+ chainSlugs: Object.keys(slugMap),
2054
+ enableTokens: true
2055
+ }).catch(console.error);
2056
+ }
2030
2057
  return true;
2031
2058
  }
2032
2059
  async accountsCreateWithSecret(_ref53) {
@@ -2253,7 +2280,7 @@ class KoniExtension {
2253
2280
  }
2254
2281
  const txObject = {
2255
2282
  gasPrice: new _bignumber.default(tx.gasPrice).toNumber(),
2256
- to: tx.action,
2283
+ to: tx.to,
2257
2284
  value: new _bignumber.default(tx.value).toNumber(),
2258
2285
  data: tx.data,
2259
2286
  nonce: new _bignumber.default(tx.nonce).toNumber(),
@@ -1151,12 +1151,12 @@ class KoniState {
1151
1151
  address: pair.address,
1152
1152
  ...pair.meta
1153
1153
  };
1154
- let qrPayload = '';
1154
+ let hashPayload = '';
1155
1155
  let canSign = false;
1156
1156
  switch (method) {
1157
1157
  case 'personal_sign':
1158
1158
  canSign = true;
1159
- qrPayload = payload;
1159
+ hashPayload = payload;
1160
1160
  break;
1161
1161
  case 'eth_sign':
1162
1162
  case 'eth_signTypedData':
@@ -1174,7 +1174,7 @@ class KoniState {
1174
1174
  account: account,
1175
1175
  type: method,
1176
1176
  payload: payload,
1177
- hashPayload: qrPayload,
1177
+ hashPayload: hashPayload,
1178
1178
  canSign: canSign,
1179
1179
  id
1180
1180
  };
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.0.9-0'
16
+ version: '1.0.9-2'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -192,10 +192,10 @@ const _TRANSFER_NOT_SUPPORTED_CHAINS = ['subspace_gemini_3a', 'kulupu', 'joystre
192
192
  exports._TRANSFER_NOT_SUPPORTED_CHAINS = _TRANSFER_NOT_SUPPORTED_CHAINS;
193
193
  const _TRANSFER_CHAIN_GROUP = {
194
194
  acala: ['karura', 'acala', 'acala_testnet'],
195
- kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'bifrost_dot', 'hydradx_main', 'mangatax_para'],
195
+ kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'hydradx_main', 'mangatax_para'],
196
196
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
197
197
  crab: ['crab', 'pangolin'],
198
- bitcountry: ['pioneer', 'bitcountry', 'bifrost'],
198
+ bitcountry: ['pioneer', 'bitcountry', 'bifrost', 'bifrost_dot'],
199
199
  statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel'],
200
200
  riochain: ['riochain'],
201
201
  sora_substrate: ['sora_substrate']
@@ -558,7 +558,7 @@ class ChainService {
558
558
  mergedChainInfoMap[storedSlug].providers = {
559
559
  ...storedChainInfo.providers,
560
560
  ...mergedChainInfoMap[storedSlug].providers
561
- };
561
+ }; // TODO: review merging providers
562
562
  this.dataMap.chainStateMap[storedSlug] = {
563
563
  currentProvider: storedChainInfo.currentProvider,
564
564
  slug: storedSlug,
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _Base = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/Base"));
9
+ var _stores = require("@subwallet/extension-base/stores");
10
+ var _util = require("@polkadot/util");
11
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
12
+ // SPDX-License-Identifier: Apache-2.0
13
+
14
+ class MigrateLedgerAccount extends _Base.default {
15
+ async run() {
16
+ try {
17
+ return new Promise(resolve => {
18
+ const store = new _stores.AccountsStore();
19
+ const update = (key, value) => {
20
+ var _value$meta;
21
+ if (key.startsWith('account:') && value.meta && (0, _util.isString)((_value$meta = value.meta) === null || _value$meta === void 0 ? void 0 : _value$meta.originGenesisHash)) {
22
+ const newValue = {
23
+ ...value
24
+ };
25
+ newValue.meta.availableGenesisHashes = [value.meta.originGenesisHash];
26
+ store.set(key, newValue);
27
+ }
28
+ };
29
+ store.allMap(map => {
30
+ Object.entries(map).forEach(_ref => {
31
+ let [key, value] = _ref;
32
+ update(key, value);
33
+ });
34
+ resolve();
35
+ });
36
+ });
37
+ } catch (e) {
38
+ console.error(e);
39
+ }
40
+ }
41
+ }
42
+ exports.default = MigrateLedgerAccount;
@@ -10,6 +10,7 @@ var _MigrateAuthUrls = _interopRequireDefault(require("@subwallet/extension-base
10
10
  var _MigrateAutoLock = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateAutoLock"));
11
11
  var _MigrateChainPatrol = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateChainPatrol"));
12
12
  var _MigrateImportedToken = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateImportedToken"));
13
+ var _MigrateLedgerAccount = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateLedgerAccount"));
13
14
  var _MigrateNetworkSettings = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateNetworkSettings"));
14
15
  var _MigrateSettings = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateSettings"));
15
16
  var _MigrateTransactionHistory = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service/scripts/MigrateTransactionHistory"));
@@ -26,7 +27,8 @@ var _default = {
26
27
  '1.0.1-50': _MigrateSettings.default,
27
28
  '1.0.1-60': _MigrateAuthUrls.default,
28
29
  '1.0.3-01': _MigrateAutoLock.default,
29
- '1.0.3-02': _MigrateChainPatrol.default
30
+ '1.0.3-02': _MigrateChainPatrol.default,
31
+ '1.0.9-01': _MigrateLedgerAccount.default
30
32
  // [`${EVERYTIME}-1`]: AutoEnableChainsTokens
31
33
  };
32
34
  exports.default = _default;
@@ -21,8 +21,9 @@ var _eth = require("@subwallet/extension-base/utils/eth");
21
21
  var _mergeTransactionAndSignature = require("@subwallet/extension-base/utils/eth/mergeTransactionAndSignature");
22
22
  var _parseTransaction = require("@subwallet/extension-base/utils/eth/parseTransaction");
23
23
  var _uiKeyring = _interopRequireDefault(require("@subwallet/ui-keyring"));
24
+ var _ethereumjsUtil = require("ethereumjs-util");
25
+ var _ethers = require("ethers");
24
26
  var _eventemitter = _interopRequireDefault(require("eventemitter3"));
25
- var _rlp = _interopRequireDefault(require("rlp"));
26
27
  var _rxjs = require("rxjs");
27
28
  var _util = require("@polkadot/util");
28
29
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
@@ -46,7 +47,7 @@ class TransactionService {
46
47
  return Object.values(this.transactions);
47
48
  }
48
49
  get processingTransactions() {
49
- return this.allTransactions.filter(t => t.status === _KoniTypes.ExtrinsicStatus.QUEUED || t.status === _KoniTypes.ExtrinsicStatus.PROCESSING);
50
+ return this.allTransactions.filter(t => t.status === _KoniTypes.ExtrinsicStatus.QUEUED || t.status === _KoniTypes.ExtrinsicStatus.SUBMITTING);
50
51
  }
51
52
  getTransaction(id) {
52
53
  return this.transactions[id];
@@ -324,7 +325,7 @@ class TransactionService {
324
325
  // Will be added in next step
325
326
  blockHash: '',
326
327
  // Will be added in next step
327
- nonce: nonce || 0,
328
+ nonce: nonce !== null && nonce !== void 0 ? nonce : 0,
328
329
  startBlock: startBlock || 0
329
330
  };
330
331
  const chainInfo = this.chainService.getChainInfoByKey(transaction.chain);
@@ -634,22 +635,21 @@ class TransactionService {
634
635
  this.eventService.emit('transaction.failed', transaction);
635
636
  }
636
637
  generateHashPayload(chain, transaction) {
638
+ var _transaction$nonce;
637
639
  const chainInfo = this.chainService.getChainInfoByKey(chain);
638
640
  const txObject = {
639
- nonce: transaction.nonce || 1,
640
- from: transaction.from,
641
- gasPrice: (0, _eth.anyNumberToBN)(transaction.gasPrice).toNumber(),
642
- gasLimit: (0, _eth.anyNumberToBN)(transaction.gas).toNumber(),
641
+ nonce: (_transaction$nonce = transaction.nonce) !== null && _transaction$nonce !== void 0 ? _transaction$nonce : 0,
642
+ gasPrice: (0, _ethereumjsUtil.addHexPrefix)((0, _eth.anyNumberToBN)(transaction.gasPrice).toString(16)),
643
+ gasLimit: (0, _ethereumjsUtil.addHexPrefix)((0, _eth.anyNumberToBN)(transaction.gas).toString(16)),
643
644
  to: transaction.to !== undefined ? transaction.to : '',
644
- value: (0, _eth.anyNumberToBN)(transaction.value).toNumber(),
645
- data: transaction.data ? transaction.data : '',
645
+ value: (0, _ethereumjsUtil.addHexPrefix)((0, _eth.anyNumberToBN)(transaction.value).toString(16)),
646
+ data: transaction.data,
646
647
  chainId: (0, _utils._getEvmChainId)(chainInfo)
647
648
  };
648
- const data = [txObject.nonce, txObject.gasPrice, txObject.gasLimit, txObject.to, txObject.value, txObject.data, txObject.chainId, new Uint8Array([0x00]), new Uint8Array([0x00])];
649
- const encoded = _rlp.default.encode(data);
650
- return (0, _util.u8aToHex)(encoded);
649
+ return _ethers.ethers.Transaction.from(txObject).unsignedSerialized;
651
650
  }
652
651
  async signAndSendEvmTransaction(_ref6) {
652
+ var _payload$nonce;
653
653
  let {
654
654
  address,
655
655
  chain,
@@ -707,13 +707,13 @@ class TransactionService {
707
707
  payload.hashPayload = this.generateHashPayload(chain, payload);
708
708
  const emitter = new _eventemitter.default();
709
709
  const txObject = {
710
- nonce: payload.nonce || 1,
710
+ nonce: (_payload$nonce = payload.nonce) !== null && _payload$nonce !== void 0 ? _payload$nonce : 0,
711
711
  from: payload.from,
712
712
  gasPrice: (0, _eth.anyNumberToBN)(payload.gasPrice).toNumber(),
713
713
  gasLimit: (0, _eth.anyNumberToBN)(payload.gas).toNumber(),
714
714
  to: payload.to !== undefined ? payload.to : '',
715
715
  value: (0, _eth.anyNumberToBN)(payload.value).toNumber(),
716
- data: payload.data ? payload.data : '',
716
+ data: payload.data,
717
717
  chainId: payload.chainId
718
718
  };
719
719
  const eventData = {
@@ -736,7 +736,7 @@ class TransactionService {
736
736
  if (!isExternal) {
737
737
  signedTransaction = payload;
738
738
  } else {
739
- const signed = (0, _mergeTransactionAndSignature.parseTxAndSignature)(txObject, payload);
739
+ const signed = (0, _mergeTransactionAndSignature.mergeTransactionAndSignature)(txObject, payload);
740
740
  const recover = web3Api.eth.accounts.recoverTransaction(signed);
741
741
  if (recover.toLowerCase() !== account.address.toLowerCase()) {
742
742
  throw new _EvmProviderError.EvmProviderError(_KoniTypes.EvmProviderErrorType.UNAUTHORIZED, 'Bad signature');
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.default = void 0;
8
7
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
9
- var _rlp = _interopRequireDefault(require("rlp"));
10
- var _util = require("@polkadot/util");
8
+ var _ethereumjsUtil = require("ethereumjs-util");
9
+ var _ethers = require("ethers");
11
10
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
12
11
  // SPDX-License-Identifier: Apache-2.0
13
12
 
@@ -30,8 +29,17 @@ class QrSigner {
30
29
  }
31
30
  async signTransaction(tx) {
32
31
  return new Promise((resolve, reject) => {
33
- const data = [tx.nonce, tx.gasPrice, tx.gasLimit, tx.to, tx.value, tx.data, tx.chainId, new Uint8Array([0x00]), new Uint8Array([0x00])];
34
- const qrPayload = _rlp.default.encode(data);
32
+ var _tx$nonce;
33
+ const txObject = {
34
+ nonce: (_tx$nonce = tx.nonce) !== null && _tx$nonce !== void 0 ? _tx$nonce : 0,
35
+ gasPrice: (0, _ethereumjsUtil.addHexPrefix)(tx.gasPrice.toString(16)),
36
+ gasLimit: (0, _ethereumjsUtil.addHexPrefix)(tx.gasLimit.toString(16)),
37
+ to: tx.to !== undefined ? tx.to : '',
38
+ value: (0, _ethereumjsUtil.addHexPrefix)(tx.value.toString(16)),
39
+ data: tx.data,
40
+ chainId: tx.chainId
41
+ };
42
+ const qrPayload = _ethers.ethers.Transaction.from(txObject).unsignedSerialized;
35
43
  const resolver = result => {
36
44
  this.#resolver();
37
45
  resolve(result);
@@ -46,7 +54,7 @@ class QrSigner {
46
54
  qrState: {
47
55
  isQrHashed: false,
48
56
  qrAddress: tx.from,
49
- qrPayload: (0, _util.u8aToHex)(qrPayload),
57
+ qrPayload: qrPayload,
50
58
  qrId: this.#id,
51
59
  isEthereum: true
52
60
  }
@@ -1,22 +1,31 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
- exports.parseTxAndSignature = void 0;
8
- var _rlp = _interopRequireDefault(require("rlp"));
9
- var _util = require("@polkadot/util");
6
+ exports.mergeTransactionAndSignature = void 0;
7
+ var _ethereumjsUtil = require("ethereumjs-util");
8
+ var _ethers = require("ethers");
10
9
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
11
10
  // SPDX-License-Identifier: Apache-2.0
12
11
 
13
- const parseTxAndSignature = (tx, _signature) => {
14
- const signature = _signature.slice(2);
15
- const r = `0x${signature.substring(0, 64)}`;
16
- const s = `0x${signature.substring(64, 128)}`;
17
- const v = `0x${signature.substring(128)}`;
18
- const data = [tx.nonce, tx.gasPrice, tx.gasLimit, tx.to, tx.value, tx.data, v, r, s];
19
- const encoded = _rlp.default.encode(data);
20
- return (0, _util.u8aToHex)(encoded);
12
+ const mergeTransactionAndSignature = (tx, _rawSignature) => {
13
+ const _signature = _rawSignature.slice(2);
14
+ const signature = {
15
+ r: `0x${_signature.substring(0, 64)}`,
16
+ s: `0x${_signature.substring(64, 128)}`,
17
+ v: parseInt(`0x${_signature.substring(128)}`)
18
+ };
19
+ const transaction = {
20
+ nonce: tx.nonce,
21
+ gasPrice: (0, _ethereumjsUtil.addHexPrefix)(tx.gasPrice.toString(16)),
22
+ gasLimit: (0, _ethereumjsUtil.addHexPrefix)(tx.gasLimit.toString(16)),
23
+ to: tx.to,
24
+ value: (0, _ethereumjsUtil.addHexPrefix)(tx.value.toString(16)),
25
+ data: tx.data,
26
+ chainId: tx.chainId,
27
+ signature: signature
28
+ };
29
+ return _ethers.ethers.Transaction.from(transaction).serialized;
21
30
  };
22
- exports.parseTxAndSignature = parseTxAndSignature;
31
+ exports.mergeTransactionAndSignature = mergeTransactionAndSignature;
@@ -129,7 +129,7 @@ class InputDataDecoder {
129
129
  if (data.indexOf('0x') !== 0) {
130
130
  data = `0x${data}`;
131
131
  }
132
- const _inputs = _ethers.ethers.utils.defaultAbiCoder.decode(types, data);
132
+ const _inputs = _ethers.ethers.AbiCoder.defaultAbiCoder().decode(types, data);
133
133
  const inputs = deepRemoveUnwantedArrayProperties(_inputs);
134
134
  return {
135
135
  methodName,
@@ -188,11 +188,11 @@ class InputDataDecoder {
188
188
  let inputs = [];
189
189
  try {
190
190
  // @ts-ignore
191
- inputs = _ethers.ethers.utils.defaultAbiCoder.decode(types, inputsBuf);
191
+ inputs = _ethers.ethers.AbiCoder.defaultAbiCoder().decode(types, inputsBuf);
192
192
  } catch (err) {
193
193
  try {
194
- const ifc = new _ethers.ethers.utils.Interface([]);
195
- inputs = ifc.decodeFunctionData(_ethers.ethers.utils.FunctionFragment.fromObject(abi), data);
194
+ const ifc = new _ethers.ethers.Interface([]);
195
+ inputs = ifc.decodeFunctionData(_ethers.ethers.FunctionFragment.from(abi), data);
196
196
  } catch (err) {}
197
197
  }
198
198
 
@@ -243,8 +243,8 @@ class InputDataDecoder {
243
243
  }
244
244
  const method = obj.name || null;
245
245
  try {
246
- const ifc = new _ethers.ethers.utils.Interface([]);
247
- const _result = ifc.decodeFunctionData(_ethers.ethers.utils.FunctionFragment.fromObject(obj), data);
246
+ const ifc = new _ethers.ethers.Interface([]);
247
+ const _result = ifc.decodeFunctionData(_ethers.ethers.FunctionFragment.from(obj), data);
248
248
  const inputs = deepRemoveUnwantedArrayProperties(_result);
249
249
  result.method = method;
250
250
  result.methodName = getMethodName(obj);
@@ -134,7 +134,6 @@ const parseContractInput = async (input, contractAddress, network) => {
134
134
  }
135
135
  }
136
136
  if (contractAddress && network) {
137
- console.log('parseOnline');
138
137
  if ((0, _utils._getEvmAbiExplorer)(network)) {
139
138
  try {
140
139
  const res = await _axios.default.get((0, _utils._getEvmAbiExplorer)(network), {
@@ -197,7 +196,7 @@ const parseEvmRlp = async (data, networkMap, evmApiMap) => {
197
196
  data: tx.data,
198
197
  gasPrice: new _bignumber.default(tx.gasPrice).toNumber(),
199
198
  gas: new _bignumber.default(tx.gas).toNumber(),
200
- to: tx.action,
199
+ to: tx.to,
201
200
  value: new _bignumber.default(tx.value).toNumber(),
202
201
  nonce: new _bignumber.default(tx.nonce).toNumber()
203
202
  };
@@ -209,13 +208,13 @@ const parseEvmRlp = async (data, networkMap, evmApiMap) => {
209
208
  return result;
210
209
  }
211
210
  }
212
- if (tx.action && network) {
213
- if (await isContractAddress(tx.action, evmApiMap[network.slug])) {
211
+ if (tx.to && network) {
212
+ if (await isContractAddress(tx.to, evmApiMap[network.slug])) {
214
213
  if ((0, _utils._getEvmAbiExplorer)(network) !== '') {
215
214
  try {
216
215
  const res = await _axios.default.get((0, _utils._getEvmAbiExplorer)(network), {
217
216
  params: {
218
- address: tx.action
217
+ address: tx.to
219
218
  },
220
219
  timeout: 2000
221
220
  });
package/cjs/utils/eth.js CHANGED
@@ -4,9 +4,9 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.signatureToHex = exports.rlpItem = exports.createTransactionFromRLP = exports.anyNumberToBN = exports.Transaction = void 0;
7
+ exports.signatureToHex = exports.createTransactionFromRLP = exports.anyNumberToBN = exports.Transaction = void 0;
8
8
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
9
- var _rlp = _interopRequireDefault(require("rlp"));
9
+ var _ethers = require("ethers");
10
10
  var _util = require("@polkadot/util");
11
11
  // Copyright 2019-2022 @subwallet/extension-base
12
12
  // SPDX-License-Identifier: Apache-2.0
@@ -20,11 +20,11 @@ const hexToNumberString = s => {
20
20
  }
21
21
  };
22
22
  class Transaction {
23
- constructor(nonce, gasPrice, gas, action, value, data, ethereumChainId) {
23
+ constructor(nonce, gasPrice, gas, to, value, data, ethereumChainId) {
24
24
  this.nonce = hexToNumberString(nonce);
25
25
  this.gasPrice = hexToNumberString(gasPrice);
26
26
  this.gas = hexToNumberString(gas);
27
- this.action = action;
27
+ this.to = to;
28
28
  this.value = hexToNumberString(value);
29
29
  this.data = data || '';
30
30
  this.ethereumChainId = parseInt(ethereumChainId, 16).toString();
@@ -42,22 +42,18 @@ const anyNumberToBN = value => {
42
42
  }
43
43
  };
44
44
  exports.anyNumberToBN = anyNumberToBN;
45
- const rlpItem = (rlp, position) => {
46
- const decodeArr = _rlp.default.decode(rlp);
47
- const u8a = decodeArr[position] || [0];
48
- return (0, _util.u8aToHex)(u8a);
49
- };
50
- exports.rlpItem = rlpItem;
51
45
  const createTransactionFromRLP = rlp => {
52
46
  try {
53
- const nonce = rlpItem(rlp, 0);
54
- const gasPrice = rlpItem(rlp, 1);
55
- const gas = rlpItem(rlp, 2);
56
- const action = rlpItem(rlp, 3);
57
- const value = rlpItem(rlp, 4);
58
- const data = rlpItem(rlp, 5);
59
- const ethereumChainId = rlpItem(rlp, 6);
60
- return new Transaction(nonce, gasPrice, gas, action, value, data, ethereumChainId);
47
+ var _transaction$gasPrice;
48
+ const transaction = _ethers.ethers.Transaction.from(rlp);
49
+ const nonce = transaction.nonce.toString(16);
50
+ const gasPrice = ((_transaction$gasPrice = transaction.gasPrice) === null || _transaction$gasPrice === void 0 ? void 0 : _transaction$gasPrice.toString(16)) || '';
51
+ const gas = transaction.gasLimit.toString(16);
52
+ const to = transaction.to || '';
53
+ const value = transaction.value.toString(16);
54
+ const data = transaction.data;
55
+ const ethereumChainId = transaction.chainId.toString(16);
56
+ return new Transaction(nonce, gasPrice, gas, to, value, data, ethereumChainId);
61
57
  } catch (e) {
62
58
  console.log(e.message);
63
59
  return null;
@@ -1688,7 +1688,7 @@ export default class KoniExtension {
1688
1688
  }
1689
1689
  } else {
1690
1690
  const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
1691
- if (_isChainEvmCompatible(chainInfo)) {
1691
+ if (_isChainEvmCompatible(chainInfo) && _isTokenTransferredByEvm(tokenInfo)) {
1692
1692
  const web3 = this.#koniState.chainService.getEvmApi(networkKey);
1693
1693
  const transaction = {
1694
1694
  value: 0,
@@ -1921,6 +1921,7 @@ export default class KoniExtension {
1921
1921
  if (!accounts.length) {
1922
1922
  throw new Error('No accounts to import');
1923
1923
  }
1924
+ const slugMap = {};
1924
1925
  for (const account of accounts) {
1925
1926
  const {
1926
1927
  accountIndex,
@@ -1928,16 +1929,36 @@ export default class KoniExtension {
1928
1929
  addressOffset,
1929
1930
  genesisHash,
1930
1931
  hardwareType,
1932
+ isEthereum,
1931
1933
  name
1932
1934
  } = account;
1933
- const key = keyring.addHardware(address, hardwareType, {
1935
+ let result;
1936
+ const baseMeta = {
1937
+ name,
1938
+ hardwareType,
1934
1939
  accountIndex,
1935
1940
  addressOffset,
1936
1941
  genesisHash,
1937
- name,
1938
1942
  originGenesisHash: genesisHash
1939
- });
1940
- const result = key.pair;
1943
+ };
1944
+ if (isEthereum) {
1945
+ result = keyring.keyring.addFromAddress(address, {
1946
+ ...baseMeta,
1947
+ isExternal: true,
1948
+ isHardware: true
1949
+ }, null, 'ethereum');
1950
+ keyring.saveAccount(result);
1951
+ slugMap.ethereum = 'ethereum';
1952
+ } else {
1953
+ result = keyring.addHardware(address, hardwareType, {
1954
+ ...baseMeta,
1955
+ availableGenesisHashes: [genesisHash]
1956
+ }).pair;
1957
+ const [slug] = this.#koniState.findNetworkKeyByGenesisHash(genesisHash);
1958
+ if (slug) {
1959
+ slugMap[slug] = slug;
1960
+ }
1961
+ }
1941
1962
  const _address = result.address;
1942
1963
  addresses.push(_address);
1943
1964
  await new Promise(resolve => {
@@ -1965,6 +1986,12 @@ export default class KoniExtension {
1965
1986
  resolve();
1966
1987
  });
1967
1988
  });
1989
+ if (Object.keys(slugMap).length) {
1990
+ this.enableChains({
1991
+ chainSlugs: Object.keys(slugMap),
1992
+ enableTokens: true
1993
+ }).catch(console.error);
1994
+ }
1968
1995
  return true;
1969
1996
  }
1970
1997
  async accountsCreateWithSecret({
@@ -2186,7 +2213,7 @@ export default class KoniExtension {
2186
2213
  }
2187
2214
  const txObject = {
2188
2215
  gasPrice: new BigN(tx.gasPrice).toNumber(),
2189
- to: tx.action,
2216
+ to: tx.to,
2190
2217
  value: new BigN(tx.value).toNumber(),
2191
2218
  data: tx.data,
2192
2219
  nonce: new BigN(tx.nonce).toNumber(),
@@ -1127,12 +1127,12 @@ export default class KoniState {
1127
1127
  address: pair.address,
1128
1128
  ...pair.meta
1129
1129
  };
1130
- let qrPayload = '';
1130
+ let hashPayload = '';
1131
1131
  let canSign = false;
1132
1132
  switch (method) {
1133
1133
  case 'personal_sign':
1134
1134
  canSign = true;
1135
- qrPayload = payload;
1135
+ hashPayload = payload;
1136
1136
  break;
1137
1137
  case 'eth_sign':
1138
1138
  case 'eth_signTypedData':
@@ -1150,7 +1150,7 @@ export default class KoniState {
1150
1150
  account: account,
1151
1151
  type: method,
1152
1152
  payload: payload,
1153
- hashPayload: qrPayload,
1153
+ hashPayload: hashPayload,
1154
1154
  canSign: canSign,
1155
1155
  id
1156
1156
  };
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.0.9-0",
20
+ "version": "1.0.9-2",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1260,6 +1260,11 @@
1260
1260
  "require": "./cjs/services/migration-service/scripts/MigrateImportedToken.js",
1261
1261
  "default": "./services/migration-service/scripts/MigrateImportedToken.js"
1262
1262
  },
1263
+ "./services/migration-service/scripts/MigrateLedgerAccount": {
1264
+ "types": "./services/migration-service/scripts/MigrateLedgerAccount.d.ts",
1265
+ "require": "./cjs/services/migration-service/scripts/MigrateLedgerAccount.js",
1266
+ "default": "./services/migration-service/scripts/MigrateLedgerAccount.js"
1267
+ },
1263
1268
  "./services/migration-service/scripts/MigrateNetworkSettings": {
1264
1269
  "types": "./services/migration-service/scripts/MigrateNetworkSettings.d.ts",
1265
1270
  "require": "./cjs/services/migration-service/scripts/MigrateNetworkSettings.js",
@@ -1707,11 +1712,11 @@
1707
1712
  "@sora-substrate/type-definitions": "^1.17.7",
1708
1713
  "@subsocial/types": "^0.6.8",
1709
1714
  "@substrate/connect": "^0.7.26",
1710
- "@subwallet/chain-list": "0.1.11-beta.1",
1711
- "@subwallet/extension-base": "^1.0.9-0",
1712
- "@subwallet/extension-chains": "^1.0.9-0",
1713
- "@subwallet/extension-dapp": "^1.0.9-0",
1714
- "@subwallet/extension-inject": "^1.0.9-0",
1715
+ "@subwallet/chain-list": "0.1.11",
1716
+ "@subwallet/extension-base": "^1.0.9-2",
1717
+ "@subwallet/extension-chains": "^1.0.9-2",
1718
+ "@subwallet/extension-dapp": "^1.0.9-2",
1719
+ "@subwallet/extension-inject": "^1.0.9-2",
1715
1720
  "@subwallet/keyring": "^0.0.10",
1716
1721
  "@subwallet/ui-keyring": "^0.0.10",
1717
1722
  "@unique-nft/types": "^0.6.0-4",
@@ -1729,7 +1734,7 @@
1729
1734
  "eth-simple-keyring": "^4.2.0",
1730
1735
  "ethereumjs-tx": "^2.1.2",
1731
1736
  "ethereumjs-util": "^7.1.5",
1732
- "ethers": "^5.7.2",
1737
+ "ethers": "^6.4.2",
1733
1738
  "eventemitter3": "^5.0.0",
1734
1739
  "file-saver": "^2.0.5",
1735
1740
  "graphql": "^16.6.0",
@@ -1741,7 +1746,6 @@
1741
1746
  "phosphor-react": "^1.4.1",
1742
1747
  "pontem-types-bundle": "^1.0.15",
1743
1748
  "protobufjs": "^7.1.2",
1744
- "rlp": "^3.0.0",
1745
1749
  "rxjs": "^7.8.0",
1746
1750
  "web3": "^1.10.0",
1747
1751
  "web3-core": "^1.10.0",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.0.9-0'
10
+ version: '1.0.9-2'
11
11
  };
@@ -176,10 +176,10 @@ export const _KNOWN_CHAIN_INFLATION_PARAMS = {
176
176
  export const _TRANSFER_NOT_SUPPORTED_CHAINS = ['subspace_gemini_3a', 'kulupu', 'joystream', 'equilibrium_parachain', 'genshiro_testnet', 'genshiro'];
177
177
  export const _TRANSFER_CHAIN_GROUP = {
178
178
  acala: ['karura', 'acala', 'acala_testnet'],
179
- kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'bifrost_dot', 'hydradx_main', 'mangatax_para'],
179
+ kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'hydradx_main', 'mangatax_para'],
180
180
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
181
181
  crab: ['crab', 'pangolin'],
182
- bitcountry: ['pioneer', 'bitcountry', 'bifrost'],
182
+ bitcountry: ['pioneer', 'bitcountry', 'bifrost', 'bifrost_dot'],
183
183
  statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel'],
184
184
  riochain: ['riochain'],
185
185
  sora_substrate: ['sora_substrate']
@@ -547,7 +547,7 @@ export class ChainService {
547
547
  mergedChainInfoMap[storedSlug].providers = {
548
548
  ...storedChainInfo.providers,
549
549
  ...mergedChainInfoMap[storedSlug].providers
550
- };
550
+ }; // TODO: review merging providers
551
551
  this.dataMap.chainStateMap[storedSlug] = {
552
552
  currentProvider: storedChainInfo.currentProvider,
553
553
  slug: storedSlug,
@@ -0,0 +1,4 @@
1
+ import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
2
+ export default class MigrateLedgerAccount extends BaseMigrationJob {
3
+ run(): Promise<void>;
4
+ }
@@ -0,0 +1,33 @@
1
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import BaseMigrationJob from '@subwallet/extension-base/services/migration-service/Base';
5
+ import { AccountsStore } from '@subwallet/extension-base/stores';
6
+ import { isString } from '@polkadot/util';
7
+ export default class MigrateLedgerAccount extends BaseMigrationJob {
8
+ async run() {
9
+ try {
10
+ return new Promise(resolve => {
11
+ const store = new AccountsStore();
12
+ const update = (key, value) => {
13
+ var _value$meta;
14
+ if (key.startsWith('account:') && value.meta && isString((_value$meta = value.meta) === null || _value$meta === void 0 ? void 0 : _value$meta.originGenesisHash)) {
15
+ const newValue = {
16
+ ...value
17
+ };
18
+ newValue.meta.availableGenesisHashes = [value.meta.originGenesisHash];
19
+ store.set(key, newValue);
20
+ }
21
+ };
22
+ store.allMap(map => {
23
+ Object.entries(map).forEach(([key, value]) => {
24
+ update(key, value);
25
+ });
26
+ resolve();
27
+ });
28
+ });
29
+ } catch (e) {
30
+ console.error(e);
31
+ }
32
+ }
33
+ }
@@ -6,6 +6,7 @@ import MigrateAuthUrls from '@subwallet/extension-base/services/migration-servic
6
6
  import MigrateAutoLock from '@subwallet/extension-base/services/migration-service/scripts/MigrateAutoLock';
7
7
  import MigrateChainPatrol from '@subwallet/extension-base/services/migration-service/scripts/MigrateChainPatrol';
8
8
  import MigrateImportedToken from '@subwallet/extension-base/services/migration-service/scripts/MigrateImportedToken';
9
+ import MigrateLedgerAccount from '@subwallet/extension-base/services/migration-service/scripts/MigrateLedgerAccount';
9
10
  import MigrateNetworkSettings from '@subwallet/extension-base/services/migration-service/scripts/MigrateNetworkSettings';
10
11
  import MigrateSettings from '@subwallet/extension-base/services/migration-service/scripts/MigrateSettings';
11
12
  import MigrateTransactionHistory from '@subwallet/extension-base/services/migration-service/scripts/MigrateTransactionHistory';
@@ -18,6 +19,7 @@ export default {
18
19
  '1.0.1-50': MigrateSettings,
19
20
  '1.0.1-60': MigrateAuthUrls,
20
21
  '1.0.3-01': MigrateAutoLock,
21
- '1.0.3-02': MigrateChainPatrol
22
+ '1.0.3-02': MigrateChainPatrol,
23
+ '1.0.9-01': MigrateLedgerAccount
22
24
  // [`${EVERYTIME}-1`]: AutoEnableChainsTokens
23
25
  };
@@ -14,13 +14,14 @@ import { parseTransferEventLogs, parseXcmEventLogs } from '@subwallet/extension-
14
14
  import { getBaseTransactionInfo, getTransactionId, isSubstrateTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
15
15
  import { getExplorerLink, parseTransactionData } from '@subwallet/extension-base/services/transaction-service/utils';
16
16
  import { anyNumberToBN } from '@subwallet/extension-base/utils/eth';
17
- import { parseTxAndSignature } from '@subwallet/extension-base/utils/eth/mergeTransactionAndSignature';
17
+ import { mergeTransactionAndSignature } from '@subwallet/extension-base/utils/eth/mergeTransactionAndSignature';
18
18
  import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
19
19
  import keyring from '@subwallet/ui-keyring';
20
+ import { addHexPrefix } from 'ethereumjs-util';
21
+ import { ethers } from 'ethers';
20
22
  import EventEmitter from 'eventemitter3';
21
- import RLP from 'rlp';
22
23
  import { BehaviorSubject } from 'rxjs';
23
- import { isHex, u8aToHex } from '@polkadot/util';
24
+ import { isHex } from '@polkadot/util';
24
25
  export default class TransactionService {
25
26
  transactionSubject = new BehaviorSubject({});
26
27
  get transactions() {
@@ -39,7 +40,7 @@ export default class TransactionService {
39
40
  return Object.values(this.transactions);
40
41
  }
41
42
  get processingTransactions() {
42
- return this.allTransactions.filter(t => t.status === ExtrinsicStatus.QUEUED || t.status === ExtrinsicStatus.PROCESSING);
43
+ return this.allTransactions.filter(t => t.status === ExtrinsicStatus.QUEUED || t.status === ExtrinsicStatus.SUBMITTING);
43
44
  }
44
45
  getTransaction(id) {
45
46
  return this.transactions[id];
@@ -317,7 +318,7 @@ export default class TransactionService {
317
318
  // Will be added in next step
318
319
  blockHash: '',
319
320
  // Will be added in next step
320
- nonce: nonce || 0,
321
+ nonce: nonce !== null && nonce !== void 0 ? nonce : 0,
321
322
  startBlock: startBlock || 0
322
323
  };
323
324
  const chainInfo = this.chainService.getChainInfoByKey(transaction.chain);
@@ -622,20 +623,18 @@ export default class TransactionService {
622
623
  this.eventService.emit('transaction.failed', transaction);
623
624
  }
624
625
  generateHashPayload(chain, transaction) {
626
+ var _transaction$nonce;
625
627
  const chainInfo = this.chainService.getChainInfoByKey(chain);
626
628
  const txObject = {
627
- nonce: transaction.nonce || 1,
628
- from: transaction.from,
629
- gasPrice: anyNumberToBN(transaction.gasPrice).toNumber(),
630
- gasLimit: anyNumberToBN(transaction.gas).toNumber(),
629
+ nonce: (_transaction$nonce = transaction.nonce) !== null && _transaction$nonce !== void 0 ? _transaction$nonce : 0,
630
+ gasPrice: addHexPrefix(anyNumberToBN(transaction.gasPrice).toString(16)),
631
+ gasLimit: addHexPrefix(anyNumberToBN(transaction.gas).toString(16)),
631
632
  to: transaction.to !== undefined ? transaction.to : '',
632
- value: anyNumberToBN(transaction.value).toNumber(),
633
- data: transaction.data ? transaction.data : '',
633
+ value: addHexPrefix(anyNumberToBN(transaction.value).toString(16)),
634
+ data: transaction.data,
634
635
  chainId: _getEvmChainId(chainInfo)
635
636
  };
636
- const data = [txObject.nonce, txObject.gasPrice, txObject.gasLimit, txObject.to, txObject.value, txObject.data, txObject.chainId, new Uint8Array([0x00]), new Uint8Array([0x00])];
637
- const encoded = RLP.encode(data);
638
- return u8aToHex(encoded);
637
+ return ethers.Transaction.from(txObject).unsignedSerialized;
639
638
  }
640
639
  async signAndSendEvmTransaction({
641
640
  address,
@@ -644,6 +643,7 @@ export default class TransactionService {
644
643
  transaction,
645
644
  url
646
645
  }) {
646
+ var _payload$nonce;
647
647
  const payload = transaction;
648
648
  const evmApi = this.chainService.getEvmApi(chain);
649
649
  const chainInfo = this.chainService.getChainInfoByKey(chain);
@@ -694,13 +694,13 @@ export default class TransactionService {
694
694
  payload.hashPayload = this.generateHashPayload(chain, payload);
695
695
  const emitter = new EventEmitter();
696
696
  const txObject = {
697
- nonce: payload.nonce || 1,
697
+ nonce: (_payload$nonce = payload.nonce) !== null && _payload$nonce !== void 0 ? _payload$nonce : 0,
698
698
  from: payload.from,
699
699
  gasPrice: anyNumberToBN(payload.gasPrice).toNumber(),
700
700
  gasLimit: anyNumberToBN(payload.gas).toNumber(),
701
701
  to: payload.to !== undefined ? payload.to : '',
702
702
  value: anyNumberToBN(payload.value).toNumber(),
703
- data: payload.data ? payload.data : '',
703
+ data: payload.data,
704
704
  chainId: payload.chainId
705
705
  };
706
706
  const eventData = {
@@ -722,7 +722,7 @@ export default class TransactionService {
722
722
  if (!isExternal) {
723
723
  signedTransaction = payload;
724
724
  } else {
725
- const signed = parseTxAndSignature(txObject, payload);
725
+ const signed = mergeTransactionAndSignature(txObject, payload);
726
726
  const recover = web3Api.eth.accounts.recoverTransaction(signed);
727
727
  if (recover.toLowerCase() !== account.address.toLowerCase()) {
728
728
  throw new EvmProviderError(EvmProviderErrorType.UNAUTHORIZED, 'Bad signature');
@@ -11,7 +11,7 @@ export interface Web3TransactionBase {
11
11
  gasLimit: number;
12
12
  nonce: number;
13
13
  chainId: number;
14
- data: string;
14
+ data?: string;
15
15
  value: number;
16
16
  }
17
17
  export interface Web3Transaction extends Web3TransactionBase {
@@ -2,8 +2,8 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { ExternalRequestPromiseStatus } from '@subwallet/extension-base/background/KoniTypes';
5
- import RLP from 'rlp';
6
- import { u8aToHex } from '@polkadot/util';
5
+ import { addHexPrefix } from 'ethereumjs-util';
6
+ import { ethers } from 'ethers';
7
7
  export default class QrSigner {
8
8
  #callback;
9
9
  #id;
@@ -22,8 +22,17 @@ export default class QrSigner {
22
22
  }
23
23
  async signTransaction(tx) {
24
24
  return new Promise((resolve, reject) => {
25
- const data = [tx.nonce, tx.gasPrice, tx.gasLimit, tx.to, tx.value, tx.data, tx.chainId, new Uint8Array([0x00]), new Uint8Array([0x00])];
26
- const qrPayload = RLP.encode(data);
25
+ var _tx$nonce;
26
+ const txObject = {
27
+ nonce: (_tx$nonce = tx.nonce) !== null && _tx$nonce !== void 0 ? _tx$nonce : 0,
28
+ gasPrice: addHexPrefix(tx.gasPrice.toString(16)),
29
+ gasLimit: addHexPrefix(tx.gasLimit.toString(16)),
30
+ to: tx.to !== undefined ? tx.to : '',
31
+ value: addHexPrefix(tx.value.toString(16)),
32
+ data: tx.data,
33
+ chainId: tx.chainId
34
+ };
35
+ const qrPayload = ethers.Transaction.from(txObject).unsignedSerialized;
27
36
  const resolver = result => {
28
37
  this.#resolver();
29
38
  resolve(result);
@@ -38,7 +47,7 @@ export default class QrSigner {
38
47
  qrState: {
39
48
  isQrHashed: false,
40
49
  qrAddress: tx.from,
41
- qrPayload: u8aToHex(qrPayload),
50
+ qrPayload: qrPayload,
42
51
  qrId: this.#id,
43
52
  isEthereum: true
44
53
  }
@@ -1,2 +1,2 @@
1
1
  import { Web3Transaction } from '@subwallet/extension-base/signers/types';
2
- export declare const parseTxAndSignature: (tx: Web3Transaction, _signature: `0x${string}`) => `0x${string}`;
2
+ export declare const mergeTransactionAndSignature: (tx: Web3Transaction, _rawSignature: `0x${string}`) => `0x${string}`;
@@ -1,14 +1,24 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import RLP from 'rlp';
5
- import { u8aToHex } from '@polkadot/util';
6
- export const parseTxAndSignature = (tx, _signature) => {
7
- const signature = _signature.slice(2);
8
- const r = `0x${signature.substring(0, 64)}`;
9
- const s = `0x${signature.substring(64, 128)}`;
10
- const v = `0x${signature.substring(128)}`;
11
- const data = [tx.nonce, tx.gasPrice, tx.gasLimit, tx.to, tx.value, tx.data, v, r, s];
12
- const encoded = RLP.encode(data);
13
- return u8aToHex(encoded);
4
+ import { addHexPrefix } from 'ethereumjs-util';
5
+ import { ethers } from 'ethers';
6
+ export const mergeTransactionAndSignature = (tx, _rawSignature) => {
7
+ const _signature = _rawSignature.slice(2);
8
+ const signature = {
9
+ r: `0x${_signature.substring(0, 64)}`,
10
+ s: `0x${_signature.substring(64, 128)}`,
11
+ v: parseInt(`0x${_signature.substring(128)}`)
12
+ };
13
+ const transaction = {
14
+ nonce: tx.nonce,
15
+ gasPrice: addHexPrefix(tx.gasPrice.toString(16)),
16
+ gasLimit: addHexPrefix(tx.gasLimit.toString(16)),
17
+ to: tx.to,
18
+ value: addHexPrefix(tx.value.toString(16)),
19
+ data: tx.data,
20
+ chainId: tx.chainId,
21
+ signature: signature
22
+ };
23
+ return ethers.Transaction.from(transaction).serialized;
14
24
  };
@@ -121,7 +121,7 @@ export class InputDataDecoder {
121
121
  if (data.indexOf('0x') !== 0) {
122
122
  data = `0x${data}`;
123
123
  }
124
- const _inputs = ethers.utils.defaultAbiCoder.decode(types, data);
124
+ const _inputs = ethers.AbiCoder.defaultAbiCoder().decode(types, data);
125
125
  const inputs = deepRemoveUnwantedArrayProperties(_inputs);
126
126
  return {
127
127
  methodName,
@@ -180,11 +180,11 @@ export class InputDataDecoder {
180
180
  let inputs = [];
181
181
  try {
182
182
  // @ts-ignore
183
- inputs = ethers.utils.defaultAbiCoder.decode(types, inputsBuf);
183
+ inputs = ethers.AbiCoder.defaultAbiCoder().decode(types, inputsBuf);
184
184
  } catch (err) {
185
185
  try {
186
- const ifc = new ethers.utils.Interface([]);
187
- inputs = ifc.decodeFunctionData(ethers.utils.FunctionFragment.fromObject(abi), data);
186
+ const ifc = new ethers.Interface([]);
187
+ inputs = ifc.decodeFunctionData(ethers.FunctionFragment.from(abi), data);
188
188
  } catch (err) {}
189
189
  }
190
190
 
@@ -235,8 +235,8 @@ export class InputDataDecoder {
235
235
  }
236
236
  const method = obj.name || null;
237
237
  try {
238
- const ifc = new ethers.utils.Interface([]);
239
- const _result = ifc.decodeFunctionData(ethers.utils.FunctionFragment.fromObject(obj), data);
238
+ const ifc = new ethers.Interface([]);
239
+ const _result = ifc.decodeFunctionData(ethers.FunctionFragment.from(obj), data);
240
240
  const inputs = deepRemoveUnwantedArrayProperties(_result);
241
241
  result.method = method;
242
242
  result.methodName = getMethodName(obj);
@@ -127,7 +127,6 @@ export const parseContractInput = async (input, contractAddress, network) => {
127
127
  }
128
128
  }
129
129
  if (contractAddress && network) {
130
- console.log('parseOnline');
131
130
  if (_getEvmAbiExplorer(network)) {
132
131
  try {
133
132
  const res = await axios.get(_getEvmAbiExplorer(network), {
@@ -189,7 +188,7 @@ export const parseEvmRlp = async (data, networkMap, evmApiMap) => {
189
188
  data: tx.data,
190
189
  gasPrice: new BigN(tx.gasPrice).toNumber(),
191
190
  gas: new BigN(tx.gas).toNumber(),
192
- to: tx.action,
191
+ to: tx.to,
193
192
  value: new BigN(tx.value).toNumber(),
194
193
  nonce: new BigN(tx.nonce).toNumber()
195
194
  };
@@ -201,13 +200,13 @@ export const parseEvmRlp = async (data, networkMap, evmApiMap) => {
201
200
  return result;
202
201
  }
203
202
  }
204
- if (tx.action && network) {
205
- if (await isContractAddress(tx.action, evmApiMap[network.slug])) {
203
+ if (tx.to && network) {
204
+ if (await isContractAddress(tx.to, evmApiMap[network.slug])) {
206
205
  if (_getEvmAbiExplorer(network) !== '') {
207
206
  try {
208
207
  const res = await axios.get(_getEvmAbiExplorer(network), {
209
208
  params: {
210
- address: tx.action
209
+ address: tx.to
211
210
  },
212
211
  timeout: 2000
213
212
  });
package/utils/eth.d.ts CHANGED
@@ -5,14 +5,13 @@ export declare class Transaction {
5
5
  readonly nonce: string;
6
6
  readonly gasPrice: string;
7
7
  readonly gas: string;
8
- readonly action: string;
8
+ readonly to: string;
9
9
  readonly value: string;
10
10
  readonly data: string;
11
11
  readonly ethereumChainId: string;
12
12
  readonly isSafe: boolean;
13
- constructor(nonce: string, gasPrice: string, gas: string, action: string, value: string, data: string, ethereumChainId: string);
13
+ constructor(nonce: string, gasPrice: string, gas: string, to: string, value: string, data: string, ethereumChainId: string);
14
14
  }
15
15
  export declare const anyNumberToBN: (value?: string | number | BNEther) => BigN;
16
- export declare const rlpItem: (rlp: string, position: number) => `0x${string}`;
17
16
  export declare const createTransactionFromRLP: (rlp: string) => Transaction | null;
18
17
  export declare const signatureToHex: (sig: SignedTransaction) => string;
package/utils/eth.js CHANGED
@@ -2,8 +2,8 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import BigN from 'bignumber.js';
5
- import RLP from 'rlp';
6
- import { hexStripPrefix, numberToHex, u8aToHex } from '@polkadot/util';
5
+ import { ethers } from 'ethers';
6
+ import { hexStripPrefix, numberToHex } from '@polkadot/util';
7
7
  const hexToNumberString = s => {
8
8
  const temp = parseInt(s, 16);
9
9
  if (isNaN(temp)) {
@@ -13,11 +13,11 @@ const hexToNumberString = s => {
13
13
  }
14
14
  };
15
15
  export class Transaction {
16
- constructor(nonce, gasPrice, gas, action, value, data, ethereumChainId) {
16
+ constructor(nonce, gasPrice, gas, to, value, data, ethereumChainId) {
17
17
  this.nonce = hexToNumberString(nonce);
18
18
  this.gasPrice = hexToNumberString(gasPrice);
19
19
  this.gas = hexToNumberString(gas);
20
- this.action = action;
20
+ this.to = to;
21
21
  this.value = hexToNumberString(value);
22
22
  this.data = data || '';
23
23
  this.ethereumChainId = parseInt(ethereumChainId, 16).toString();
@@ -33,21 +33,18 @@ export const anyNumberToBN = value => {
33
33
  return new BigN(value.toNumber());
34
34
  }
35
35
  };
36
- export const rlpItem = (rlp, position) => {
37
- const decodeArr = RLP.decode(rlp);
38
- const u8a = decodeArr[position] || [0];
39
- return u8aToHex(u8a);
40
- };
41
36
  export const createTransactionFromRLP = rlp => {
42
37
  try {
43
- const nonce = rlpItem(rlp, 0);
44
- const gasPrice = rlpItem(rlp, 1);
45
- const gas = rlpItem(rlp, 2);
46
- const action = rlpItem(rlp, 3);
47
- const value = rlpItem(rlp, 4);
48
- const data = rlpItem(rlp, 5);
49
- const ethereumChainId = rlpItem(rlp, 6);
50
- return new Transaction(nonce, gasPrice, gas, action, value, data, ethereumChainId);
38
+ var _transaction$gasPrice;
39
+ const transaction = ethers.Transaction.from(rlp);
40
+ const nonce = transaction.nonce.toString(16);
41
+ const gasPrice = ((_transaction$gasPrice = transaction.gasPrice) === null || _transaction$gasPrice === void 0 ? void 0 : _transaction$gasPrice.toString(16)) || '';
42
+ const gas = transaction.gasLimit.toString(16);
43
+ const to = transaction.to || '';
44
+ const value = transaction.value.toString(16);
45
+ const data = transaction.data;
46
+ const ethereumChainId = transaction.chainId.toString(16);
47
+ return new Transaction(nonce, gasPrice, gas, to, value, data, ethereumChainId);
51
48
  } catch (e) {
52
49
  console.log(e.message);
53
50
  return null;