@subwallet/extension-base 1.0.2-1b → 1.0.2-3
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/background/KoniTypes.d.ts +31 -5
- package/background/KoniTypes.js +2 -1
- package/background/errors/TransactionError.js +4 -0
- package/background/types.d.ts +10 -5
- package/cjs/background/KoniTypes.js +2 -1
- package/cjs/background/errors/TransactionError.js +4 -0
- package/cjs/koni/api/dotsama/transfer.js +6 -12
- package/cjs/koni/api/nft/acala_nft/index.js +7 -10
- package/cjs/koni/api/nft/bit.country/index.js +7 -9
- package/cjs/koni/api/nft/evm_nft/index.js +2 -1
- package/cjs/koni/api/nft/karura_nft/index.js +7 -9
- package/cjs/koni/api/nft/rmrk_nft/index.js +4 -1
- package/cjs/koni/api/nft/statemine_nft/index.js +7 -9
- package/cjs/koni/api/nft/unique_nft/index.js +5 -6
- package/cjs/koni/api/nft/wasm_nft/index.js +2 -1
- package/cjs/koni/api/staking/bonding/relayChain.js +3 -0
- package/cjs/koni/background/cron.js +53 -46
- package/cjs/koni/background/handlers/Extension.js +292 -159
- package/cjs/koni/background/handlers/State.js +24 -14
- package/cjs/koni/background/handlers/Tabs.js +42 -16
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/handler/light-client/index.js +0 -2
- package/cjs/services/chain-service/index.js +53 -38
- package/cjs/services/history-service/index.js +3 -3
- package/cjs/services/history-service/subsquid-multi-chain-history.js +1 -1
- package/cjs/services/keyring-service/index.js +11 -13
- package/cjs/services/request-service/handler/AuthRequestHandler.js +7 -5
- package/cjs/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/cjs/services/request-service/index.js +14 -5
- package/cjs/services/storage-service/DatabaseService.js +8 -5
- package/cjs/services/storage-service/db-stores/Nft.js +9 -4
- package/cjs/services/transaction-service/index.js +3 -1
- package/cjs/utils/address.js +10 -1
- package/cjs/utils/index.js +2 -1
- package/koni/api/dotsama/transfer.js +6 -12
- package/koni/api/nft/acala_nft/index.js +7 -9
- package/koni/api/nft/bit.country/index.js +7 -8
- package/koni/api/nft/evm_nft/index.js +2 -1
- package/koni/api/nft/index.d.ts +1 -1
- package/koni/api/nft/karura_nft/index.js +7 -8
- package/koni/api/nft/nft.d.ts +1 -1
- package/koni/api/nft/rmrk_nft/index.js +4 -1
- package/koni/api/nft/statemine_nft/index.js +7 -8
- package/koni/api/nft/unique_nft/index.js +5 -5
- package/koni/api/nft/wasm_nft/index.js +2 -1
- package/koni/api/staking/bonding/relayChain.js +3 -0
- package/koni/background/cron.js +53 -46
- package/koni/background/handlers/Extension.d.ts +6 -1
- package/koni/background/handlers/Extension.js +203 -73
- package/koni/background/handlers/State.d.ts +1 -1
- package/koni/background/handlers/State.js +26 -14
- package/koni/background/handlers/Tabs.js +42 -16
- package/package.json +13 -13
- package/packageInfo.js +1 -1
- package/services/chain-service/handler/light-client/index.d.ts +1 -17
- package/services/chain-service/handler/light-client/index.js +1 -1
- package/services/chain-service/index.d.ts +3 -2
- package/services/chain-service/index.js +47 -33
- package/services/chain-service/types.d.ts +1 -0
- package/services/history-service/index.d.ts +3 -1
- package/services/history-service/index.js +3 -3
- package/services/history-service/subsquid-multi-chain-history.js +1 -1
- package/services/keyring-service/index.d.ts +4 -2
- package/services/keyring-service/index.js +11 -13
- package/services/request-service/handler/AuthRequestHandler.d.ts +3 -1
- package/services/request-service/handler/AuthRequestHandler.js +7 -5
- package/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/services/request-service/index.d.ts +3 -1
- package/services/request-service/index.js +14 -5
- package/services/storage-service/DatabaseService.d.ts +1 -1
- package/services/storage-service/DatabaseService.js +8 -5
- package/services/storage-service/db-stores/Nft.d.ts +2 -1
- package/services/storage-service/db-stores/Nft.js +9 -4
- package/services/transaction-service/index.js +3 -1
- package/utils/address.d.ts +3 -0
- package/utils/address.js +8 -1
- package/utils/index.d.ts +1 -1
- package/utils/index.js +1 -1
|
@@ -20,16 +20,17 @@ import { getPSP34TransferExtrinsic } from '@subwallet/extension-base/koni/api/to
|
|
|
20
20
|
import { createXcmExtrinsic } from '@subwallet/extension-base/koni/api/xcm';
|
|
21
21
|
import { _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _getSubstrateGenesisHash, _getTokenMinAmount, _isAssetSmartContractNft, _isChainEvmCompatible, _isCustomAsset, _isLocalToken, _isNativeToken, _isTokenEvmSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
22
22
|
import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
|
|
23
|
+
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
24
|
+
import { convertSubjectInfoToAddresses } from '@subwallet/extension-base/utils/address';
|
|
23
25
|
import { createTransactionFromRLP, signatureToHex } from '@subwallet/extension-base/utils/eth';
|
|
24
26
|
import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
|
|
25
27
|
import { createPair } from '@subwallet/keyring';
|
|
26
28
|
import { keyring } from '@subwallet/ui-keyring';
|
|
27
|
-
import { accounts as accountsObservable } from '@subwallet/ui-keyring/observable/accounts';
|
|
28
29
|
import BigN from 'bignumber.js';
|
|
29
30
|
import { Transaction } from 'ethereumjs-tx';
|
|
30
31
|
import { TypeRegistry } from '@polkadot/types';
|
|
31
|
-
import { assert, BN, hexStripPrefix, hexToU8a, isAscii, isHex, u8aToHex, u8aToString } from '@polkadot/util';
|
|
32
|
-
import { base64Decode, isEthereumAddress, jsonDecrypt, keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
|
|
32
|
+
import { assert, BN, BN_ZERO, hexStripPrefix, hexToU8a, isAscii, isHex, u8aToHex, u8aToString } from '@polkadot/util';
|
|
33
|
+
import { base64Decode, decodeAddress, isAddress, isEthereumAddress, jsonDecrypt, keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
|
|
33
34
|
const ETH_DERIVE_DEFAULT = '/m/44\'/60\'/0\'/0/0';
|
|
34
35
|
function getSuri(seed, type) {
|
|
35
36
|
return type === 'ethereum' ? `${seed}${ETH_DERIVE_DEFAULT}` : seed;
|
|
@@ -163,7 +164,8 @@ export default class KoniExtension {
|
|
|
163
164
|
// FIXME This looks very much like what we have in Tabs
|
|
164
165
|
accountsSubscribe(id, port) {
|
|
165
166
|
const cb = createSubscription(id, port);
|
|
166
|
-
const
|
|
167
|
+
const accountSubject = this.#koniState.keyringService.accountSubject;
|
|
168
|
+
const subscription = accountSubject.subscribe(accounts => cb(transformAccounts(accounts)));
|
|
167
169
|
port.onDisconnect.addListener(() => {
|
|
168
170
|
this.cancelSubscription(id);
|
|
169
171
|
subscription.unsubscribe();
|
|
@@ -404,8 +406,7 @@ export default class KoniExtension {
|
|
|
404
406
|
const keyringService = this.#koniState.keyringService;
|
|
405
407
|
await this.#koniState.eventService.waitAccountReady;
|
|
406
408
|
const currentAccount = keyringService.currentAccount;
|
|
407
|
-
const
|
|
408
|
-
const transformedAccounts = transformAccounts(accountsSubject.value);
|
|
409
|
+
const transformedAccounts = transformAccounts(keyringService.accounts);
|
|
409
410
|
const responseData = {
|
|
410
411
|
accounts: transformedAccounts !== null && transformedAccounts !== void 0 && transformedAccounts.length ? [{
|
|
411
412
|
...ACCOUNT_ALL_JSON
|
|
@@ -413,7 +414,7 @@ export default class KoniExtension {
|
|
|
413
414
|
currentAddress: currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.address,
|
|
414
415
|
currentGenesisHash: currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.currentGenesisHash
|
|
415
416
|
};
|
|
416
|
-
const subscriptionAccounts =
|
|
417
|
+
const subscriptionAccounts = keyringService.accountSubject.subscribe(storedAccounts => {
|
|
417
418
|
const transformedAccounts = transformAccounts(storedAccounts);
|
|
418
419
|
responseData.accounts = transformedAccounts !== null && transformedAccounts !== void 0 && transformedAccounts.length ? [{
|
|
419
420
|
...ACCOUNT_ALL_JSON
|
|
@@ -448,25 +449,66 @@ export default class KoniExtension {
|
|
|
448
449
|
});
|
|
449
450
|
return id;
|
|
450
451
|
}
|
|
451
|
-
|
|
452
|
+
subscribeAddresses(id, port) {
|
|
453
|
+
const _cb = createSubscription(id, port);
|
|
454
|
+
const subscription = this.#koniState.keyringService.addressesSubject.subscribe(subjectInfo => {
|
|
455
|
+
const addresses = convertSubjectInfoToAddresses(subjectInfo);
|
|
456
|
+
_cb({
|
|
457
|
+
addresses: addresses
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
this.createUnsubscriptionHandle(id, subscription.unsubscribe);
|
|
461
|
+
port.onDisconnect.addListener(() => {
|
|
462
|
+
this.cancelSubscription(id);
|
|
463
|
+
});
|
|
464
|
+
const subjectInfo = this.#koniState.keyringService.addresses;
|
|
465
|
+
return {
|
|
466
|
+
addresses: convertSubjectInfoToAddresses(subjectInfo)
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
saveRecentAccount({
|
|
452
470
|
accountId
|
|
453
471
|
}) {
|
|
454
|
-
|
|
472
|
+
if (isAddress(accountId)) {
|
|
473
|
+
const address = reformatAddress(accountId);
|
|
474
|
+
const account = keyring.getAccount(address);
|
|
475
|
+
const contact = keyring.getAddress(address);
|
|
476
|
+
return account || contact || {
|
|
477
|
+
...keyring.saveRecent(accountId).json,
|
|
478
|
+
publicKey: decodeAddress(address)
|
|
479
|
+
};
|
|
480
|
+
} else {
|
|
481
|
+
throw Error('Invalid address');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
editContactAccount({
|
|
485
|
+
address,
|
|
486
|
+
meta
|
|
487
|
+
}) {
|
|
488
|
+
if (isAddress(address)) {
|
|
489
|
+
const _address = reformatAddress(address);
|
|
490
|
+
keyring.saveAddress(_address, meta);
|
|
491
|
+
return true;
|
|
492
|
+
} else {
|
|
493
|
+
throw Error('Invalid address');
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
deleteContactAccount({
|
|
497
|
+
address
|
|
498
|
+
}) {
|
|
499
|
+
if (isAddress(address)) {
|
|
500
|
+
const _address = reformatAddress(address);
|
|
501
|
+
keyring.forgetAddress(_address);
|
|
502
|
+
return true;
|
|
503
|
+
} else {
|
|
504
|
+
throw Error('Invalid address');
|
|
505
|
+
}
|
|
455
506
|
}
|
|
456
|
-
|
|
457
|
-
// private triggerAccountsSubscription (): boolean {
|
|
458
|
-
// const accountsSubject = accountsObservable.subject;
|
|
459
|
-
//
|
|
460
|
-
// accountsSubject.next(accountsSubject.getValue());
|
|
461
|
-
//
|
|
462
|
-
// return true;
|
|
463
|
-
// }
|
|
464
|
-
|
|
465
507
|
_getAuthListV2() {
|
|
508
|
+
const keyringService = this.#koniState.keyringService;
|
|
466
509
|
return new Promise((resolve, reject) => {
|
|
467
510
|
this.#koniState.getAuthorize(rs => {
|
|
468
|
-
const
|
|
469
|
-
const addressList = Object.keys(accounts);
|
|
511
|
+
const addressList = Object.keys(keyringService.accounts);
|
|
470
512
|
const urlList = Object.keys(rs);
|
|
471
513
|
if (Object.keys(rs[urlList[0]].isAllowedMap).toString() !== addressList.toString()) {
|
|
472
514
|
urlList.forEach(url => {
|
|
@@ -580,7 +622,7 @@ export default class KoniExtension {
|
|
|
580
622
|
return true;
|
|
581
623
|
}
|
|
582
624
|
getNonReadonlyAccounts() {
|
|
583
|
-
const storedAccounts =
|
|
625
|
+
const storedAccounts = this.#koniState.keyringService.accounts;
|
|
584
626
|
const transformedAccounts = transformAccounts(storedAccounts);
|
|
585
627
|
return transformedAccounts.filter(a => !a.isReadOnly).map(a => a.address);
|
|
586
628
|
}
|
|
@@ -1281,6 +1323,14 @@ export default class KoniExtension {
|
|
|
1281
1323
|
});
|
|
1282
1324
|
return historySubject.getValue();
|
|
1283
1325
|
}
|
|
1326
|
+
addContact(to) {
|
|
1327
|
+
const toAddress = reformatAddress(to);
|
|
1328
|
+
const account = keyring.getAccount(toAddress);
|
|
1329
|
+
const contact = keyring.getAddress(toAddress);
|
|
1330
|
+
if (!account && (!contact || contact.meta.isRecent)) {
|
|
1331
|
+
keyring.saveAddress(toAddress, {});
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1284
1334
|
validateTransfer(tokenSlug, from, to, value, transferAll) {
|
|
1285
1335
|
const errors = [];
|
|
1286
1336
|
const keypair = keyring.getPair(from);
|
|
@@ -1354,6 +1404,7 @@ export default class KoniExtension {
|
|
|
1354
1404
|
});
|
|
1355
1405
|
}
|
|
1356
1406
|
const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
|
|
1407
|
+
this.addContact(to);
|
|
1357
1408
|
return this.#koniState.transactionService.handleTransaction({
|
|
1358
1409
|
errors,
|
|
1359
1410
|
warnings,
|
|
@@ -1406,6 +1457,7 @@ export default class KoniExtension {
|
|
|
1406
1457
|
substrateApi
|
|
1407
1458
|
});
|
|
1408
1459
|
}
|
|
1460
|
+
this.addContact(to);
|
|
1409
1461
|
return await this.#koniState.transactionService.handleTransaction({
|
|
1410
1462
|
url: EXTENSION_REQUEST_URL,
|
|
1411
1463
|
address: from,
|
|
@@ -1415,6 +1467,7 @@ export default class KoniExtension {
|
|
|
1415
1467
|
extrinsicType: ExtrinsicType.TRANSFER_XCM,
|
|
1416
1468
|
chainType: ChainType.SUBSTRATE,
|
|
1417
1469
|
transferNativeAmount: _isNativeToken(originTokenInfo) ? value : '0',
|
|
1470
|
+
isTransferAll: inputData.transferAll,
|
|
1418
1471
|
errors
|
|
1419
1472
|
});
|
|
1420
1473
|
}
|
|
@@ -1428,6 +1481,7 @@ export default class KoniExtension {
|
|
|
1428
1481
|
const contractAddress = params.contractAddress;
|
|
1429
1482
|
const tokenId = params.tokenId;
|
|
1430
1483
|
const transaction = await getERC721Transaction(this.#koniState.getEvmApi(networkKey), contractAddress, senderAddress, recipientAddress, tokenId);
|
|
1484
|
+
this.addContact(recipientAddress);
|
|
1431
1485
|
return await this.#koniState.transactionService.handleTransaction({
|
|
1432
1486
|
address: senderAddress,
|
|
1433
1487
|
chain: networkKey,
|
|
@@ -1503,6 +1557,71 @@ export default class KoniExtension {
|
|
|
1503
1557
|
}) {
|
|
1504
1558
|
return await this.#koniState.balanceService.getTokenFreeBalance(address, networkKey, token);
|
|
1505
1559
|
}
|
|
1560
|
+
async transferGetMaxTransferable({
|
|
1561
|
+
address,
|
|
1562
|
+
destChain,
|
|
1563
|
+
isXcmTransfer,
|
|
1564
|
+
networkKey,
|
|
1565
|
+
token
|
|
1566
|
+
}) {
|
|
1567
|
+
const freeBalance = await this.#koniState.balanceService.getTokenFreeBalance(address, networkKey, token);
|
|
1568
|
+
const tokenInfo = token ? this.#koniState.chainService.getAssetBySlug(token) : this.#koniState.chainService.getNativeTokenInfo(networkKey);
|
|
1569
|
+
if (!_isNativeToken(tokenInfo)) {
|
|
1570
|
+
return freeBalance;
|
|
1571
|
+
} else {
|
|
1572
|
+
const substrateApi = this.#koniState.chainService.getSubstrateApi(networkKey);
|
|
1573
|
+
let estimatedFee;
|
|
1574
|
+
let maxTransferable = new BN(freeBalance.value);
|
|
1575
|
+
if (isXcmTransfer) {
|
|
1576
|
+
const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
|
|
1577
|
+
const destinationTokenInfo = this.#koniState.getXcmEqualAssetByChain(destChain, tokenInfo.slug);
|
|
1578
|
+
if (!destinationTokenInfo) {
|
|
1579
|
+
estimatedFee = '0';
|
|
1580
|
+
} else {
|
|
1581
|
+
maxTransferable = maxTransferable.sub(new BN(tokenInfo.minAmount || '0'));
|
|
1582
|
+
const mockTx = await createXcmExtrinsic({
|
|
1583
|
+
chainInfoMap,
|
|
1584
|
+
destinationTokenInfo,
|
|
1585
|
+
originTokenInfo: tokenInfo,
|
|
1586
|
+
recipient: address,
|
|
1587
|
+
sendingValue: '0',
|
|
1588
|
+
substrateApi
|
|
1589
|
+
});
|
|
1590
|
+
try {
|
|
1591
|
+
var _paymentInfo$partialF;
|
|
1592
|
+
const paymentInfo = await mockTx.paymentInfo(address);
|
|
1593
|
+
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0';
|
|
1594
|
+
} catch (e) {
|
|
1595
|
+
estimatedFee = '0';
|
|
1596
|
+
console.warn('Error estimating fee', e);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
} else {
|
|
1600
|
+
const [mockTx] = await createTransferExtrinsic({
|
|
1601
|
+
from: address,
|
|
1602
|
+
networkKey,
|
|
1603
|
+
substrateApi,
|
|
1604
|
+
to: address,
|
|
1605
|
+
tokenInfo,
|
|
1606
|
+
transferAll: true,
|
|
1607
|
+
value: '0'
|
|
1608
|
+
});
|
|
1609
|
+
try {
|
|
1610
|
+
var _paymentInfo$partialF2;
|
|
1611
|
+
const paymentInfo = await (mockTx === null || mockTx === void 0 ? void 0 : mockTx.paymentInfo(address));
|
|
1612
|
+
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF2 = paymentInfo.partialFee) === null || _paymentInfo$partialF2 === void 0 ? void 0 : _paymentInfo$partialF2.toString()) || '0';
|
|
1613
|
+
} catch (e) {
|
|
1614
|
+
estimatedFee = '0';
|
|
1615
|
+
console.warn('Error estimating fee', e);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
maxTransferable = maxTransferable.sub(new BN(estimatedFee));
|
|
1619
|
+
return {
|
|
1620
|
+
...freeBalance,
|
|
1621
|
+
value: maxTransferable.gt(BN_ZERO) ? maxTransferable.toString() || '0' : '0'
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1506
1625
|
async subscribeAddressFreeBalance({
|
|
1507
1626
|
address,
|
|
1508
1627
|
networkKey,
|
|
@@ -1549,6 +1668,7 @@ export default class KoniExtension {
|
|
|
1549
1668
|
const networkKey = params === null || params === void 0 ? void 0 : params.networkKey;
|
|
1550
1669
|
const apiProps = this.#koniState.getSubstrateApi(networkKey);
|
|
1551
1670
|
const extrinsic = !isPSP34 ? getNftTransferExtrinsic(networkKey, apiProps, senderAddress, recipientAddress, params || {}) : await getPSP34TransferExtrinsic(networkKey, apiProps, senderAddress, recipientAddress, params || {});
|
|
1671
|
+
this.addContact(recipientAddress);
|
|
1552
1672
|
const rs = await this.#koniState.transactionService.handleTransaction({
|
|
1553
1673
|
address: senderAddress,
|
|
1554
1674
|
chain: networkKey,
|
|
@@ -1582,23 +1702,6 @@ export default class KoniExtension {
|
|
|
1582
1702
|
meta: pair.meta
|
|
1583
1703
|
};
|
|
1584
1704
|
}
|
|
1585
|
-
|
|
1586
|
-
// private async isInWalletAccount (address?: string) {
|
|
1587
|
-
// return new Promise((resolve) => {
|
|
1588
|
-
// if (address) {
|
|
1589
|
-
// accountsObservable.subject.subscribe((storedAccounts: SubjectInfo): void => {
|
|
1590
|
-
// if (storedAccounts[address]) {
|
|
1591
|
-
// resolve(true);
|
|
1592
|
-
// }
|
|
1593
|
-
//
|
|
1594
|
-
// resolve(false);
|
|
1595
|
-
// });
|
|
1596
|
-
// } else {
|
|
1597
|
-
// resolve(false);
|
|
1598
|
-
// }
|
|
1599
|
-
// });
|
|
1600
|
-
// }
|
|
1601
|
-
|
|
1602
1705
|
accountsTie2({
|
|
1603
1706
|
address,
|
|
1604
1707
|
genesisHash
|
|
@@ -2729,8 +2832,6 @@ export default class KoniExtension {
|
|
|
2729
2832
|
return this.accountsCreateSuri(request);
|
|
2730
2833
|
case 'pri(accounts.changePassword)':
|
|
2731
2834
|
return this.accountsChangePassword(request);
|
|
2732
|
-
case 'pri(accounts.edit)':
|
|
2733
|
-
return this.accountsEdit(request);
|
|
2734
2835
|
case 'pri(accounts.export)':
|
|
2735
2836
|
return this.accountsExport(request);
|
|
2736
2837
|
case 'pri(accounts.show)':
|
|
@@ -2799,38 +2900,6 @@ export default class KoniExtension {
|
|
|
2799
2900
|
return this.getAuthListV2();
|
|
2800
2901
|
case 'pri(authorize.toggle)':
|
|
2801
2902
|
return this.toggleAuthorization2(request);
|
|
2802
|
-
case 'pri(accounts.create.suriV2)':
|
|
2803
|
-
return await this.accountsCreateSuriV2(request);
|
|
2804
|
-
case 'pri(accounts.forget)':
|
|
2805
|
-
return await this.accountsForgetOverride(request);
|
|
2806
|
-
case 'pri(accounts.create.externalV2)':
|
|
2807
|
-
return await this.accountsCreateExternalV2(request);
|
|
2808
|
-
case 'pri(accounts.create.hardwareV2)':
|
|
2809
|
-
return await this.accountsCreateHardwareV2(request);
|
|
2810
|
-
case 'pri(accounts.create.hardwareMultiple)':
|
|
2811
|
-
return await this.accountsCreateHardwareMultiple(request);
|
|
2812
|
-
case 'pri(accounts.create.withSecret)':
|
|
2813
|
-
return await this.accountsCreateWithSecret(request);
|
|
2814
|
-
case 'pri(seed.createV2)':
|
|
2815
|
-
return this.seedCreateV2(request);
|
|
2816
|
-
case 'pri(seed.validateV2)':
|
|
2817
|
-
return this.seedValidateV2(request);
|
|
2818
|
-
case 'pri(privateKey.validateV2)':
|
|
2819
|
-
return this.metamaskPrivateKeyValidateV2(request);
|
|
2820
|
-
case 'pri(accounts.exportPrivateKey)':
|
|
2821
|
-
return this.accountExportPrivateKey(request);
|
|
2822
|
-
case 'pri(accounts.checkPublicAndSecretKey)':
|
|
2823
|
-
return this.checkPublicAndSecretKey(request);
|
|
2824
|
-
case 'pri(accounts.subscribeWithCurrentAddress)':
|
|
2825
|
-
return await this.accountsGetAllWithCurrentAddress(id, port);
|
|
2826
|
-
case 'pri(accounts.subscribeAccountsInputAddress)':
|
|
2827
|
-
return this.accountsGetAll(id, port);
|
|
2828
|
-
case 'pri(accounts.saveRecent)':
|
|
2829
|
-
return this.saveRecentAccountId(request);
|
|
2830
|
-
case 'pri(currentAccount.saveAddress)':
|
|
2831
|
-
return await this.saveCurrentAccountAddress(request);
|
|
2832
|
-
case 'pri(accounts.updateCurrentAddress)':
|
|
2833
|
-
return this.updateCurrentAccountAddress(request);
|
|
2834
2903
|
case 'pri(settings.changeBalancesVisibility)':
|
|
2835
2904
|
return this.toggleBalancesVisibility(id, port);
|
|
2836
2905
|
case 'pri(settings.subscribe)':
|
|
@@ -2880,6 +2949,65 @@ export default class KoniExtension {
|
|
|
2880
2949
|
case 'pri(transaction.history.getSubscription)':
|
|
2881
2950
|
return await this.subscribeHistory(id, port);
|
|
2882
2951
|
|
|
2952
|
+
/// Account management
|
|
2953
|
+
// Add account
|
|
2954
|
+
case 'pri(accounts.create.suriV2)':
|
|
2955
|
+
return await this.accountsCreateSuriV2(request);
|
|
2956
|
+
case 'pri(accounts.create.externalV2)':
|
|
2957
|
+
return await this.accountsCreateExternalV2(request);
|
|
2958
|
+
case 'pri(accounts.create.hardwareV2)':
|
|
2959
|
+
return await this.accountsCreateHardwareV2(request);
|
|
2960
|
+
case 'pri(accounts.create.hardwareMultiple)':
|
|
2961
|
+
return await this.accountsCreateHardwareMultiple(request);
|
|
2962
|
+
case 'pri(accounts.create.withSecret)':
|
|
2963
|
+
return await this.accountsCreateWithSecret(request);
|
|
2964
|
+
case 'pri(seed.createV2)':
|
|
2965
|
+
return this.seedCreateV2(request);
|
|
2966
|
+
|
|
2967
|
+
// Remove account
|
|
2968
|
+
case 'pri(accounts.forget)':
|
|
2969
|
+
return await this.accountsForgetOverride(request);
|
|
2970
|
+
|
|
2971
|
+
// Validate account
|
|
2972
|
+
case 'pri(seed.validateV2)':
|
|
2973
|
+
return this.seedValidateV2(request);
|
|
2974
|
+
case 'pri(privateKey.validateV2)':
|
|
2975
|
+
return this.metamaskPrivateKeyValidateV2(request);
|
|
2976
|
+
case 'pri(accounts.checkPublicAndSecretKey)':
|
|
2977
|
+
return this.checkPublicAndSecretKey(request);
|
|
2978
|
+
|
|
2979
|
+
// Export account
|
|
2980
|
+
case 'pri(accounts.exportPrivateKey)':
|
|
2981
|
+
return this.accountExportPrivateKey(request);
|
|
2982
|
+
|
|
2983
|
+
// Subscribe account
|
|
2984
|
+
case 'pri(accounts.subscribeWithCurrentAddress)':
|
|
2985
|
+
return await this.accountsGetAllWithCurrentAddress(id, port);
|
|
2986
|
+
case 'pri(accounts.subscribeAccountsInputAddress)':
|
|
2987
|
+
return this.accountsGetAll(id, port);
|
|
2988
|
+
|
|
2989
|
+
// Save current account
|
|
2990
|
+
case 'pri(currentAccount.saveAddress)':
|
|
2991
|
+
return await this.saveCurrentAccountAddress(request);
|
|
2992
|
+
case 'pri(accounts.updateCurrentAddress)':
|
|
2993
|
+
return this.updateCurrentAccountAddress(request);
|
|
2994
|
+
|
|
2995
|
+
// Edit account
|
|
2996
|
+
case 'pri(accounts.edit)':
|
|
2997
|
+
return this.accountsEdit(request);
|
|
2998
|
+
|
|
2999
|
+
// Save contact address
|
|
3000
|
+
case 'pri(accounts.saveRecent)':
|
|
3001
|
+
return this.saveRecentAccount(request);
|
|
3002
|
+
case 'pri(accounts.editContact)':
|
|
3003
|
+
return this.editContactAccount(request);
|
|
3004
|
+
case 'pri(accounts.deleteContact)':
|
|
3005
|
+
return this.deleteContactAccount(request);
|
|
3006
|
+
|
|
3007
|
+
// Subscribe address
|
|
3008
|
+
case 'pri(accounts.subscribeAddresses)':
|
|
3009
|
+
return this.subscribeAddresses(id, port);
|
|
3010
|
+
|
|
2883
3011
|
// ChainService
|
|
2884
3012
|
case 'pri(chainService.subscribeChainInfoMap)':
|
|
2885
3013
|
return this.subscribeChainInfoMap(id, port);
|
|
@@ -2923,6 +3051,8 @@ export default class KoniExtension {
|
|
|
2923
3051
|
return await this.transferCheckSupporting(request);
|
|
2924
3052
|
case 'pri(transfer.getExistentialDeposit)':
|
|
2925
3053
|
return this.transferGetExistentialDeposit(request);
|
|
3054
|
+
case 'pri(transfer.getMaxTransferable)':
|
|
3055
|
+
return this.transferGetMaxTransferable(request);
|
|
2926
3056
|
case 'pri(freeBalance.get)':
|
|
2927
3057
|
return this.getAddressFreeBalance(request);
|
|
2928
3058
|
case 'pri(freeBalance.subscribe)':
|
|
@@ -2934,7 +3064,7 @@ export default class KoniExtension {
|
|
|
2934
3064
|
case 'pri(accounts.get.meta)':
|
|
2935
3065
|
return this.getAccountMeta(request);
|
|
2936
3066
|
|
|
2937
|
-
|
|
3067
|
+
/// Send NFT
|
|
2938
3068
|
case 'pri(evmNft.submitTransaction)':
|
|
2939
3069
|
return this.evmNftSubmitTransaction(request);
|
|
2940
3070
|
case 'pri(substrateNft.submitTransaction)':
|
|
@@ -109,7 +109,7 @@ export default class KoniState {
|
|
|
109
109
|
resetNft(newAddress: string): void;
|
|
110
110
|
updateNftData(network: string, nftData: NftItem, address: string, callback?: (nftData: NftItem) => void): void;
|
|
111
111
|
deleteNftCollection(chain: string, collectionId: string): Promise<void>;
|
|
112
|
-
cleanUpNfts(chain: string, owner: string, collectionId: string, nftIds: string[]): void;
|
|
112
|
+
cleanUpNfts(chain: string, owner: string, collectionId: string[], nftIds: string[], ownNothing?: boolean): void;
|
|
113
113
|
getNft(): Promise<NftJson | undefined>;
|
|
114
114
|
subscribeNft(): Subject<NftJson>;
|
|
115
115
|
resetStakingReward(): void;
|
|
@@ -27,7 +27,6 @@ import AccountRefStore from '@subwallet/extension-base/stores/AccountRef';
|
|
|
27
27
|
import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
|
|
28
28
|
import { decodePair } from '@subwallet/keyring/pair/decode';
|
|
29
29
|
import { keyring } from '@subwallet/ui-keyring';
|
|
30
|
-
import { accounts } from '@subwallet/ui-keyring/observable/accounts';
|
|
31
30
|
import SimpleKeyring from 'eth-simple-keyring';
|
|
32
31
|
import { Subject } from 'rxjs';
|
|
33
32
|
import { assert, BN, hexStripPrefix, hexToU8a, isHex, logger as createLogger, u8aToHex } from '@polkadot/util';
|
|
@@ -84,10 +83,10 @@ export default class KoniState {
|
|
|
84
83
|
this.notificationService = new NotificationService();
|
|
85
84
|
this.chainService = new ChainService(this.dbService, this.eventService);
|
|
86
85
|
this.settingService = new SettingService();
|
|
87
|
-
this.requestService = new RequestService(this.chainService, this.settingService);
|
|
86
|
+
this.requestService = new RequestService(this.chainService, this.settingService, this.keyringService);
|
|
88
87
|
this.priceService = new PriceService(this.dbService, this.eventService, this.chainService);
|
|
89
88
|
this.balanceService = new BalanceService(this.chainService);
|
|
90
|
-
this.historyService = new HistoryService(this.dbService, this.chainService, this.eventService);
|
|
89
|
+
this.historyService = new HistoryService(this.dbService, this.chainService, this.eventService, this.keyringService);
|
|
91
90
|
this.transactionService = new TransactionService(this.chainService, this.eventService, this.requestService, this.balanceService, this.historyService, this.notificationService, this.dbService);
|
|
92
91
|
this.migrationService = new MigrationService(this);
|
|
93
92
|
this.subscription = new KoniSubscription(this, this.dbService);
|
|
@@ -252,7 +251,7 @@ export default class KoniState {
|
|
|
252
251
|
return this.requestService.getAuthList();
|
|
253
252
|
}
|
|
254
253
|
getAddressList(value = false) {
|
|
255
|
-
const addressList = Object.keys(
|
|
254
|
+
const addressList = Object.keys(this.keyringService.accounts);
|
|
256
255
|
return addressList.reduce((addressList, v) => ({
|
|
257
256
|
...addressList,
|
|
258
257
|
[v]: value
|
|
@@ -356,8 +355,8 @@ export default class KoniState {
|
|
|
356
355
|
deleteNftCollection(chain, collectionId) {
|
|
357
356
|
return this.dbService.deleteNftCollection(chain, collectionId);
|
|
358
357
|
}
|
|
359
|
-
cleanUpNfts(chain, owner, collectionId, nftIds) {
|
|
360
|
-
this.dbService.cleanUpNft(chain, owner, collectionId, nftIds).catch(e => this.logger.warn(e));
|
|
358
|
+
cleanUpNfts(chain, owner, collectionId, nftIds, ownNothing) {
|
|
359
|
+
this.dbService.cleanUpNft(chain, owner, collectionId, nftIds, ownNothing).catch(e => this.logger.warn(e));
|
|
361
360
|
}
|
|
362
361
|
async getNft() {
|
|
363
362
|
const addresses = this.getDecodedAddresses();
|
|
@@ -530,7 +529,11 @@ export default class KoniState {
|
|
|
530
529
|
isApproved
|
|
531
530
|
}) => {
|
|
532
531
|
if (isApproved) {
|
|
533
|
-
|
|
532
|
+
if (networkData.mode === 'insert') {
|
|
533
|
+
await this.upsertChainInfo(networkData);
|
|
534
|
+
} else {
|
|
535
|
+
// TODO: update existed network (need more discussion)
|
|
536
|
+
}
|
|
534
537
|
return null;
|
|
535
538
|
} else {
|
|
536
539
|
throw new EvmProviderError(EvmProviderErrorType.USER_REJECTED_REQUEST);
|
|
@@ -987,7 +990,10 @@ export default class KoniState {
|
|
|
987
990
|
if (!chainId) {
|
|
988
991
|
return [undefined, undefined];
|
|
989
992
|
}
|
|
990
|
-
const rs = Object.entries(this.chainService.getChainInfoMap()).find(([networkKey, chainInfo]) =>
|
|
993
|
+
const rs = Object.entries(this.chainService.getChainInfoMap()).find(([networkKey, chainInfo]) => {
|
|
994
|
+
var _chainInfo$evmInfo;
|
|
995
|
+
return (chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$evmInfo = chainInfo.evmInfo) === null || _chainInfo$evmInfo === void 0 ? void 0 : _chainInfo$evmInfo.evmChainId) === chainId;
|
|
996
|
+
});
|
|
991
997
|
if (rs) {
|
|
992
998
|
return rs;
|
|
993
999
|
} else {
|
|
@@ -1221,17 +1227,23 @@ export default class KoniState {
|
|
|
1221
1227
|
account: account,
|
|
1222
1228
|
canSign: true
|
|
1223
1229
|
};
|
|
1230
|
+
const eType = transaction.value ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.EVM_EXECUTE;
|
|
1231
|
+
const transactionData = {
|
|
1232
|
+
...transaction
|
|
1233
|
+
};
|
|
1234
|
+
if (eType === ExtrinsicType.TRANSFER_BALANCE) {
|
|
1235
|
+
// @ts-ignore
|
|
1236
|
+
transactionData.tokenSlug = this.chainService.getNativeTokenInfo(networkKey).slug;
|
|
1237
|
+
}
|
|
1224
1238
|
|
|
1225
|
-
//
|
|
1239
|
+
// Custom handle this instead of general handler transaction
|
|
1226
1240
|
const transactionEmitter = await this.transactionService.addTransaction({
|
|
1227
1241
|
transaction: requestPayload,
|
|
1228
1242
|
address: requestPayload.from,
|
|
1229
1243
|
chain: networkKey,
|
|
1230
1244
|
url,
|
|
1231
|
-
data:
|
|
1232
|
-
|
|
1233
|
-
},
|
|
1234
|
-
extrinsicType: transaction.value ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.EVM_EXECUTE,
|
|
1245
|
+
data: transactionData,
|
|
1246
|
+
extrinsicType: eType,
|
|
1235
1247
|
chainType: ChainType.EVM
|
|
1236
1248
|
});
|
|
1237
1249
|
|
|
@@ -1356,7 +1368,7 @@ export default class KoniState {
|
|
|
1356
1368
|
var _currentAssetSettings;
|
|
1357
1369
|
const chain = SUBSCAN_CHAIN_MAP_REVERSE[network];
|
|
1358
1370
|
const chainInfo = chain ? chainMap[chain] : null;
|
|
1359
|
-
const balanceIsEmpty = (!balance || balance === '0') && !locked
|
|
1371
|
+
const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
|
|
1360
1372
|
|
|
1361
1373
|
// Cancel if chain is not supported or is testnet or balance is 0
|
|
1362
1374
|
if (!chainInfo || chainInfo.isTestnet || balanceIsEmpty) {
|
|
@@ -13,7 +13,6 @@ import { PHISHING_PAGE_REDIRECT } from '@subwallet/extension-base/defaults';
|
|
|
13
13
|
import { _generateCustomProviderKey } from '@subwallet/extension-base/services/chain-service/utils';
|
|
14
14
|
import { canDerive } from '@subwallet/extension-base/utils';
|
|
15
15
|
import keyring from '@subwallet/ui-keyring';
|
|
16
|
-
import { accounts as accountsObservable } from '@subwallet/ui-keyring/observable/accounts';
|
|
17
16
|
import Web3 from 'web3';
|
|
18
17
|
import { checkIfDenied } from '@polkadot/phishing';
|
|
19
18
|
import { assert, isNumber } from '@polkadot/util';
|
|
@@ -182,13 +181,13 @@ export default class KoniTabs {
|
|
|
182
181
|
anyType
|
|
183
182
|
}) {
|
|
184
183
|
const authInfo = await this.getAuthInfo(url);
|
|
185
|
-
return transformAccountsV2(
|
|
184
|
+
return transformAccountsV2(this.#koniState.keyringService.accounts, anyType, authInfo, accountAuthType);
|
|
186
185
|
}
|
|
187
186
|
accountsSubscribeV2(url, {
|
|
188
187
|
accountAuthType
|
|
189
188
|
}, id, port) {
|
|
190
189
|
const cb = createSubscription(id, port);
|
|
191
|
-
const subscription =
|
|
190
|
+
const subscription = this.#koniState.keyringService.accountSubject.subscribe(accounts => {
|
|
192
191
|
this.getAuthInfo(url).then(authInfo => {
|
|
193
192
|
cb(transformAccountsV2(accounts, false, authInfo, accountAuthType));
|
|
194
193
|
}).catch(console.error);
|
|
@@ -213,7 +212,7 @@ export default class KoniTabs {
|
|
|
213
212
|
async getEvmCurrentAccount(url, getAll = false) {
|
|
214
213
|
return await new Promise(resolve => {
|
|
215
214
|
this.getAuthInfo(url).then(authInfo => {
|
|
216
|
-
const allAccounts =
|
|
215
|
+
const allAccounts = this.#koniState.keyringService.accounts;
|
|
217
216
|
const accountList = transformAccountsV2(allAccounts, false, authInfo, 'evm').map(a => a.address);
|
|
218
217
|
let accounts = [];
|
|
219
218
|
const address = this.#koniState.keyringService.currentAccount.address;
|
|
@@ -250,8 +249,8 @@ export default class KoniTabs {
|
|
|
250
249
|
slug
|
|
251
250
|
} = currentEvmNetwork;
|
|
252
251
|
const evmApi = this.#koniState.getEvmApi(slug);
|
|
253
|
-
const web3 = evmApi.api;
|
|
254
|
-
if (web3.currentProvider instanceof Web3.providers.WebsocketProvider) {
|
|
252
|
+
const web3 = evmApi === null || evmApi === void 0 ? void 0 : evmApi.api;
|
|
253
|
+
if ((web3 === null || web3 === void 0 ? void 0 : web3.currentProvider) instanceof Web3.providers.WebsocketProvider) {
|
|
255
254
|
if (!web3.currentProvider.connected) {
|
|
256
255
|
console.log(`[Web3] ${slug} is disconnected, trying to connect...`);
|
|
257
256
|
this.#koniState.refreshWeb3Api(slug);
|
|
@@ -336,12 +335,16 @@ export default class KoniTabs {
|
|
|
336
335
|
contractAddress: input.options.address,
|
|
337
336
|
originChain: chain
|
|
338
337
|
});
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
338
|
+
|
|
339
|
+
// Below code is comment because we will handle exited token in the ui-view
|
|
340
|
+
// if (validate.isExist) {
|
|
341
|
+
// throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Current token is existed');
|
|
342
|
+
// } else
|
|
343
|
+
if (validate.contractError) {
|
|
342
344
|
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Contract address is invalid');
|
|
343
345
|
}
|
|
344
346
|
const tokenInfo = {
|
|
347
|
+
slug: validate === null || validate === void 0 ? void 0 : validate.existedSlug,
|
|
345
348
|
type: tokenType,
|
|
346
349
|
name: validate.name,
|
|
347
350
|
contractAddress: input.options.address,
|
|
@@ -364,16 +367,38 @@ export default class KoniTabs {
|
|
|
364
367
|
} = input[0];
|
|
365
368
|
if (chainId) {
|
|
366
369
|
const chainIdNum = parseInt(chainId, 16);
|
|
367
|
-
const [
|
|
368
|
-
if (
|
|
370
|
+
const [existedNetworkSlug, existedChainInfo] = this.#koniState.findNetworkKeyByChainId(chainIdNum);
|
|
371
|
+
if (existedNetworkSlug && existedChainInfo && existedChainInfo !== null && existedChainInfo !== void 0 && existedChainInfo.evmInfo) {
|
|
372
|
+
const evmInfo = existedChainInfo.evmInfo;
|
|
373
|
+
const substrateInfo = existedChainInfo.substrateInfo;
|
|
374
|
+
const chainState = this.#koniState.getChainStateByKey(existedNetworkSlug);
|
|
375
|
+
await this.#koniState.addNetworkConfirm(id, url, {
|
|
376
|
+
mode: 'update',
|
|
377
|
+
chainSpec: {
|
|
378
|
+
evmChainId: evmInfo.evmChainId,
|
|
379
|
+
decimals: evmInfo.decimals,
|
|
380
|
+
existentialDeposit: evmInfo.existentialDeposit,
|
|
381
|
+
genesisHash: (substrateInfo === null || substrateInfo === void 0 ? void 0 : substrateInfo.genesisHash) || '',
|
|
382
|
+
paraId: (substrateInfo === null || substrateInfo === void 0 ? void 0 : substrateInfo.paraId) || null,
|
|
383
|
+
addressPrefix: (substrateInfo === null || substrateInfo === void 0 ? void 0 : substrateInfo.addressPrefix) || 0
|
|
384
|
+
},
|
|
385
|
+
chainEditInfo: {
|
|
386
|
+
blockExplorer: blockExplorerUrls === null || blockExplorerUrls === void 0 ? void 0 : blockExplorerUrls[0],
|
|
387
|
+
slug: existedNetworkSlug,
|
|
388
|
+
currentProvider: chainState.currentProvider,
|
|
389
|
+
providers: existedChainInfo.providers,
|
|
390
|
+
symbol: evmInfo.symbol,
|
|
391
|
+
chainType: 'EVM',
|
|
392
|
+
name: existedChainInfo.name
|
|
393
|
+
}
|
|
394
|
+
});
|
|
369
395
|
return await this.switchEvmChain(id, url, {
|
|
370
396
|
method: 'wallet_switchEthereumChain',
|
|
371
397
|
params: [{
|
|
372
398
|
chainId
|
|
373
399
|
}]
|
|
374
400
|
});
|
|
375
|
-
}
|
|
376
|
-
if (rpcUrls && chainName) {
|
|
401
|
+
} else if (rpcUrls && chainName) {
|
|
377
402
|
const filteredUrls = rpcUrls.filter(targetString => {
|
|
378
403
|
let url;
|
|
379
404
|
try {
|
|
@@ -414,6 +439,8 @@ export default class KoniTabs {
|
|
|
414
439
|
name: chainInfo.name
|
|
415
440
|
}
|
|
416
441
|
});
|
|
442
|
+
} else {
|
|
443
|
+
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Invalid provider');
|
|
417
444
|
}
|
|
418
445
|
}
|
|
419
446
|
}
|
|
@@ -668,9 +695,8 @@ export default class KoniTabs {
|
|
|
668
695
|
if (e.code) {
|
|
669
696
|
throw e;
|
|
670
697
|
} else {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, e.message);
|
|
698
|
+
console.error(e);
|
|
699
|
+
throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, e === null || e === void 0 ? void 0 : e.toString());
|
|
674
700
|
}
|
|
675
701
|
}
|
|
676
702
|
}
|