@subwallet/extension-base 1.3.42-0 → 1.3.43-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/background/KoniTypes.d.ts +35 -23
- package/background/errors/BitcoinProviderError.d.ts +1 -1
- package/background/errors/BitcoinProviderError.js +2 -2
- package/background/types.d.ts +1 -1
- package/cjs/background/errors/BitcoinProviderError.js +2 -2
- package/cjs/core/logic-validation/request.js +316 -3
- package/cjs/koni/background/handlers/Extension.js +418 -90
- package/cjs/koni/background/handlers/State.js +198 -6
- package/cjs/koni/background/handlers/Tabs.js +119 -6
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/bitcoin/index.js +67 -0
- package/cjs/page/index.js +5 -0
- package/cjs/services/buy-service/index.js +17 -2
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +27 -5
- package/cjs/services/request-service/handler/AuthRequestHandler.js +18 -0
- package/cjs/services/request-service/handler/BitcoinRequestHandler.js +48 -61
- package/cjs/services/request-service/index.js +2 -2
- package/cjs/services/transaction-service/index.js +71 -2
- package/cjs/utils/auth.js +2 -1
- package/core/logic-validation/request.d.ts +6 -2
- package/core/logic-validation/request.js +309 -3
- package/koni/background/handlers/Extension.d.ts +3 -0
- package/koni/background/handlers/Extension.js +330 -6
- package/koni/background/handlers/State.d.ts +4 -1
- package/koni/background/handlers/State.js +189 -4
- package/koni/background/handlers/Tabs.d.ts +7 -2
- package/koni/background/handlers/Tabs.js +119 -9
- package/package.json +11 -6
- package/packageInfo.js +1 -1
- package/page/bitcoin/index.d.ts +17 -0
- package/page/bitcoin/index.js +60 -0
- package/page/index.d.ts +2 -1
- package/page/index.js +4 -0
- package/services/balance-service/transfer/cardano-transfer.d.ts +2 -0
- package/services/buy-service/index.js +17 -2
- package/services/earning-service/handlers/native-staking/para-chain.js +27 -5
- package/services/request-service/handler/AuthRequestHandler.js +19 -1
- package/services/request-service/handler/BitcoinRequestHandler.d.ts +3 -4
- package/services/request-service/handler/BitcoinRequestHandler.js +48 -61
- package/services/request-service/index.d.ts +1 -2
- package/services/request-service/index.js +2 -2
- package/services/transaction-service/index.d.ts +1 -0
- package/services/transaction-service/index.js +71 -2
- package/services/transaction-service/types.d.ts +1 -0
- package/types/balance/transfer.d.ts +4 -2
- package/types/buy.d.ts +1 -1
- package/utils/auth.js +3 -2
|
@@ -8,7 +8,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
8
8
|
import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
|
|
9
9
|
import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
|
|
10
10
|
import { CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, MantaPayEnableMessage, StakingType } from '@subwallet/extension-base/background/KoniTypes';
|
|
11
|
-
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, LATEST_SESSION } from '@subwallet/extension-base/constants';
|
|
11
|
+
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, BTC_DUST_AMOUNT, LATEST_SESSION } from '@subwallet/extension-base/constants';
|
|
12
12
|
import { additionalValidateTransferForRecipient, validateTransferRequest, validateXcmMinAmountToMythos, validateXcmTransferRequest } from '@subwallet/extension-base/core/logic-validation/transfer';
|
|
13
13
|
import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
|
|
14
14
|
import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
|
|
@@ -38,7 +38,7 @@ import { _isPosChainBridge, getClaimPosBridge } from '@subwallet/extension-base/
|
|
|
38
38
|
import { estimateXcmFee } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
|
|
39
39
|
import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
|
|
40
40
|
import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
|
|
41
|
-
import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _isAssetSmartContractNft, _isChainEnabled, _isChainEvmCompatible, _isChainSubstrateCompatible, _isCustomAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isNativeTokenBySlug, _isPureEvmChain, _isTokenEvmSmartContract, _isTokenTransferredByBitcoin, _isTokenTransferredByCardano, _isTokenTransferredByEvm, _isTokenTransferredByTon } from '@subwallet/extension-base/services/chain-service/utils';
|
|
41
|
+
import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _isAssetSmartContractNft, _isChainBitcoinCompatible, _isChainEnabled, _isChainEvmCompatible, _isChainSubstrateCompatible, _isCustomAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isNativeTokenBySlug, _isPureEvmChain, _isTokenEvmSmartContract, _isTokenTransferredByBitcoin, _isTokenTransferredByCardano, _isTokenTransferredByEvm, _isTokenTransferredByTon } from '@subwallet/extension-base/services/chain-service/utils';
|
|
42
42
|
import { calculateToAmountByReservePool } from '@subwallet/extension-base/services/fee-service/utils';
|
|
43
43
|
import { batchExtrinsicSetFeeHydration, getAssetHubTokensCanPayFee, getHydrationTokensCanPayFee } from '@subwallet/extension-base/services/fee-service/utils/tokenPayFee';
|
|
44
44
|
import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
|
|
@@ -47,11 +47,12 @@ import { isProposalExpired, isSupportWalletConnectChain, isSupportWalletConnectN
|
|
|
47
47
|
import { SWStorage } from '@subwallet/extension-base/storage';
|
|
48
48
|
import { AccountsStore } from '@subwallet/extension-base/stores';
|
|
49
49
|
import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, CommonStepType, EarningProcessType, ProcessType, StakingTxErrorType, StepStatus, SwapFeeType, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
|
|
50
|
-
import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, getAccountSignMode, isSameAddress, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
|
|
50
|
+
import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
|
|
51
51
|
import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
|
|
52
52
|
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
53
53
|
import { getKeypairTypeByAddress, isAddress, isCardanoAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
|
|
54
|
-
import { CardanoKeypairTypes, EthereumKeypairTypes, SubstrateKeypairTypes, TonKeypairTypes } from '@subwallet/keyring/types';
|
|
54
|
+
import { BitcoinKeypairTypes, CardanoKeypairTypes, EthereumKeypairTypes, SubstrateKeypairTypes, TonKeypairTypes } from '@subwallet/keyring/types';
|
|
55
|
+
import { getBitcoinAddressInfo } from '@subwallet/keyring/utils';
|
|
55
56
|
import { isBitcoinAddress } from '@subwallet/keyring/utils/address/validate';
|
|
56
57
|
import { keyring } from '@subwallet/ui-keyring';
|
|
57
58
|
import { getSdkError } from '@walletconnect/utils';
|
|
@@ -566,7 +567,8 @@ export default class KoniExtension {
|
|
|
566
567
|
evm: EthereumKeypairTypes,
|
|
567
568
|
substrate: SubstrateKeypairTypes,
|
|
568
569
|
ton: TonKeypairTypes,
|
|
569
|
-
cardano: CardanoKeypairTypes
|
|
570
|
+
cardano: CardanoKeypairTypes,
|
|
571
|
+
bitcoin: BitcoinKeypairTypes
|
|
570
572
|
};
|
|
571
573
|
return !!accountAuthTypes && accountAuthTypes.some(authType => {
|
|
572
574
|
var _validTypes$authType;
|
|
@@ -668,7 +670,8 @@ export default class KoniExtension {
|
|
|
668
670
|
substrate: 'substrateInfo',
|
|
669
671
|
evm: 'evmInfo',
|
|
670
672
|
cardano: 'cardanoInfo',
|
|
671
|
-
ton: 'tonInfo'
|
|
673
|
+
ton: 'tonInfo',
|
|
674
|
+
bitcoin: 'bitcoinInfo'
|
|
672
675
|
};
|
|
673
676
|
const typeInfoKey = typeInfoMap[authSwitchNetworkType];
|
|
674
677
|
if (!typeInfoKey || !chainInfo[typeInfoKey]) {
|
|
@@ -1351,6 +1354,7 @@ export default class KoniExtension {
|
|
|
1351
1354
|
if (transferAll) {
|
|
1352
1355
|
inputData.value = transferAmount.value;
|
|
1353
1356
|
}
|
|
1357
|
+
console.log('PSPT transaction', transaction.toHex());
|
|
1354
1358
|
} else {
|
|
1355
1359
|
const substrateApi = this.#koniState.getSubstrateApi(chain);
|
|
1356
1360
|
[transaction, transferAmount.value] = await createSubstrateExtrinsic({
|
|
@@ -1662,6 +1666,190 @@ export default class KoniExtension {
|
|
|
1662
1666
|
eventsHandler: eventsHandler
|
|
1663
1667
|
});
|
|
1664
1668
|
}
|
|
1669
|
+
async makeBitcoinDappTransferConfirmation(inputData) {
|
|
1670
|
+
const {
|
|
1671
|
+
chain,
|
|
1672
|
+
feeCustom,
|
|
1673
|
+
feeOption,
|
|
1674
|
+
from,
|
|
1675
|
+
id,
|
|
1676
|
+
to,
|
|
1677
|
+
tokenSlug,
|
|
1678
|
+
transferAll,
|
|
1679
|
+
value
|
|
1680
|
+
} = inputData;
|
|
1681
|
+
const transferTokenInfo = this.#koniState.chainService.getAssetBySlug(tokenSlug);
|
|
1682
|
+
const errors = validateTransferRequest(transferTokenInfo, from, to, value, transferAll);
|
|
1683
|
+
const warnings = [];
|
|
1684
|
+
const chainInfo = this.#koniState.getChainInfo(chain);
|
|
1685
|
+
const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain);
|
|
1686
|
+
const nativeTokenSlug = nativeTokenInfo.slug;
|
|
1687
|
+
const isTransferNativeToken = nativeTokenSlug === tokenSlug;
|
|
1688
|
+
let chainType = ChainType.BITCOIN;
|
|
1689
|
+
const tokenBaseAmount = {
|
|
1690
|
+
value: '0',
|
|
1691
|
+
symbol: transferTokenInfo.symbol,
|
|
1692
|
+
decimals: transferTokenInfo.decimals || 0
|
|
1693
|
+
};
|
|
1694
|
+
const transferAmount = {
|
|
1695
|
+
...tokenBaseAmount
|
|
1696
|
+
};
|
|
1697
|
+
let transaction;
|
|
1698
|
+
let overrideFeeCustom;
|
|
1699
|
+
let calculatedBitcoinFeeRate;
|
|
1700
|
+
|
|
1701
|
+
// Get native token amount
|
|
1702
|
+
const freeBalance = await this.getAddressTransferableBalance({
|
|
1703
|
+
address: from,
|
|
1704
|
+
networkKey: chain,
|
|
1705
|
+
token: tokenSlug
|
|
1706
|
+
});
|
|
1707
|
+
const txVal = transferAll ? freeBalance.value : value || '0';
|
|
1708
|
+
try {
|
|
1709
|
+
if (_isChainBitcoinCompatible(chainInfo)) {
|
|
1710
|
+
chainType = ChainType.BITCOIN;
|
|
1711
|
+
const bitcoinApi = this.#koniState.getBitcoinApi(chain); // Get Bitcoin API map
|
|
1712
|
+
const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
|
|
1713
|
+
const feeInfo = await this.#koniState.feeService.subscribeChainFee(getId(), chain, 'bitcoin');
|
|
1714
|
+
[transaction, transferAmount.value, calculatedBitcoinFeeRate] = await createBitcoinTransaction({
|
|
1715
|
+
bitcoinApi,
|
|
1716
|
+
chain,
|
|
1717
|
+
from,
|
|
1718
|
+
feeInfo,
|
|
1719
|
+
to,
|
|
1720
|
+
transferAll: transferAll,
|
|
1721
|
+
value: txVal,
|
|
1722
|
+
network: network
|
|
1723
|
+
});
|
|
1724
|
+
if (calculatedBitcoinFeeRate) {
|
|
1725
|
+
const feeRate = parseFloat(calculatedBitcoinFeeRate);
|
|
1726
|
+
if (!isNaN(feeRate)) {
|
|
1727
|
+
overrideFeeCustom = {
|
|
1728
|
+
feeRate
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
} catch (e) {
|
|
1734
|
+
const error = e;
|
|
1735
|
+
if (error.message.includes('transfer amount exceeds balance')) {
|
|
1736
|
+
error.message = t('Insufficient balance');
|
|
1737
|
+
}
|
|
1738
|
+
throw error;
|
|
1739
|
+
}
|
|
1740
|
+
const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
|
|
1741
|
+
return this.#koniState.transactionService.handleTransactionAfterConfirmation({
|
|
1742
|
+
id,
|
|
1743
|
+
errors,
|
|
1744
|
+
warnings,
|
|
1745
|
+
address: from,
|
|
1746
|
+
chain: chain,
|
|
1747
|
+
feeCustom: overrideFeeCustom || feeCustom,
|
|
1748
|
+
feeOption: overrideFeeCustom ? 'custom' : feeOption,
|
|
1749
|
+
chainType,
|
|
1750
|
+
transferNativeAmount,
|
|
1751
|
+
transaction,
|
|
1752
|
+
data: inputData,
|
|
1753
|
+
extrinsicType: isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN,
|
|
1754
|
+
ignoreWarnings: [],
|
|
1755
|
+
isTransferAll: isTransferNativeToken ? transferAll : false,
|
|
1756
|
+
edAsWarning: isTransferNativeToken
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
async makePsbtTransferAfterConfirmation(inputData_) {
|
|
1760
|
+
var _txOutput$;
|
|
1761
|
+
const {
|
|
1762
|
+
chain,
|
|
1763
|
+
from,
|
|
1764
|
+
id,
|
|
1765
|
+
psbt,
|
|
1766
|
+
tokenSlug,
|
|
1767
|
+
txInput,
|
|
1768
|
+
txOutput,
|
|
1769
|
+
value
|
|
1770
|
+
} = inputData_;
|
|
1771
|
+
let inputAmount = new BigN(0);
|
|
1772
|
+
const transferTokenInfo = this.#koniState.chainService.getAssetBySlug(tokenSlug);
|
|
1773
|
+
const totalUtxoInput = txInput.reduce((total, {
|
|
1774
|
+
address,
|
|
1775
|
+
amount
|
|
1776
|
+
}) => {
|
|
1777
|
+
if (!address || !amount) {
|
|
1778
|
+
return total;
|
|
1779
|
+
}
|
|
1780
|
+
if (isSameAddress(address, from)) {
|
|
1781
|
+
inputAmount = new BigN(amount);
|
|
1782
|
+
}
|
|
1783
|
+
return total.plus(new BigN(amount || 0));
|
|
1784
|
+
}, new BigN(0));
|
|
1785
|
+
const totalUtxoOutput = txOutput.reduce((total, {
|
|
1786
|
+
address,
|
|
1787
|
+
amount
|
|
1788
|
+
}) => {
|
|
1789
|
+
if (!address || !amount) {
|
|
1790
|
+
return total;
|
|
1791
|
+
}
|
|
1792
|
+
return total.plus(new BigN(amount));
|
|
1793
|
+
}, new BigN(0));
|
|
1794
|
+
const estimateFeeValue = totalUtxoInput.minus(totalUtxoOutput).toString();
|
|
1795
|
+
const errors = validateTransferRequest(transferTokenInfo, from, ((_txOutput$ = txOutput[0]) === null || _txOutput$ === void 0 ? void 0 : _txOutput$.address) || '', value, false);
|
|
1796
|
+
const warnings = [];
|
|
1797
|
+
const chainInfo = this.#koniState.getChainInfo(chain);
|
|
1798
|
+
const {
|
|
1799
|
+
decimals,
|
|
1800
|
+
symbol
|
|
1801
|
+
} = _getChainNativeTokenBasicInfo(chainInfo);
|
|
1802
|
+
const estimateFee = {
|
|
1803
|
+
symbol,
|
|
1804
|
+
decimals,
|
|
1805
|
+
value: estimateFeeValue,
|
|
1806
|
+
tooHigh: false
|
|
1807
|
+
};
|
|
1808
|
+
const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain);
|
|
1809
|
+
const nativeTokenSlug = nativeTokenInfo.slug;
|
|
1810
|
+
const isTransferNativeToken = nativeTokenSlug === tokenSlug;
|
|
1811
|
+
const chainType = ChainType.BITCOIN;
|
|
1812
|
+
const bitcoinNetwork = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
|
|
1813
|
+
const psbtGenerate = bitcoin.Psbt.fromHex(psbt, {
|
|
1814
|
+
network: bitcoinNetwork
|
|
1815
|
+
});
|
|
1816
|
+
const tokenBaseAmount = {
|
|
1817
|
+
value: inputData_.value,
|
|
1818
|
+
symbol: transferTokenInfo.symbol,
|
|
1819
|
+
decimals: transferTokenInfo.decimals || 0
|
|
1820
|
+
};
|
|
1821
|
+
const transferAmount = {
|
|
1822
|
+
...tokenBaseAmount
|
|
1823
|
+
};
|
|
1824
|
+
|
|
1825
|
+
// Get native token amount
|
|
1826
|
+
const freeBalance = await this.getAddressTransferableBalance({
|
|
1827
|
+
address: from,
|
|
1828
|
+
networkKey: chain,
|
|
1829
|
+
token: tokenSlug
|
|
1830
|
+
});
|
|
1831
|
+
if (new BigN(freeBalance.value).lt(inputAmount)) {
|
|
1832
|
+
throw new Error(t('Insufficient balance'));
|
|
1833
|
+
}
|
|
1834
|
+
const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
|
|
1835
|
+
return this.#koniState.transactionService.handleTransactionAfterConfirmation({
|
|
1836
|
+
id,
|
|
1837
|
+
errors,
|
|
1838
|
+
warnings,
|
|
1839
|
+
address: from,
|
|
1840
|
+
chain: chain,
|
|
1841
|
+
estimateFee,
|
|
1842
|
+
chainType,
|
|
1843
|
+
transferNativeAmount,
|
|
1844
|
+
transaction: psbtGenerate,
|
|
1845
|
+
data: inputData_,
|
|
1846
|
+
extrinsicType: isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN,
|
|
1847
|
+
ignoreWarnings: [],
|
|
1848
|
+
isTransferAll: false,
|
|
1849
|
+
edAsWarning: isTransferNativeToken,
|
|
1850
|
+
skipFeeRecalculation: true
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1665
1853
|
async getTokensCanPayFee(request) {
|
|
1666
1854
|
var _tokensHasBalanceInfo;
|
|
1667
1855
|
const {
|
|
@@ -1982,6 +2170,135 @@ export default class KoniExtension {
|
|
|
1982
2170
|
});
|
|
1983
2171
|
return calculateMaxTransferable(id, _request, freeBalance, fee);
|
|
1984
2172
|
}
|
|
2173
|
+
async subscribeTransferableWhenConfirmation({
|
|
2174
|
+
address,
|
|
2175
|
+
chain,
|
|
2176
|
+
feeCustom,
|
|
2177
|
+
feeOption: _feeOptions,
|
|
2178
|
+
to,
|
|
2179
|
+
token,
|
|
2180
|
+
value
|
|
2181
|
+
}, id, port) {
|
|
2182
|
+
const cb = createSubscription(id, port);
|
|
2183
|
+
const freeBalanceSubject = new Subject();
|
|
2184
|
+
const feeSubject = new Subject();
|
|
2185
|
+
const feeType = 'bitcoin';
|
|
2186
|
+
let error;
|
|
2187
|
+
const convertData = async (freeBalance, fee, feeOption, feeCustom) => {
|
|
2188
|
+
let estimatedFee = '0';
|
|
2189
|
+
let feeOptions = null;
|
|
2190
|
+
const amount = parseInt(value || '0');
|
|
2191
|
+
const neededUtxos = [];
|
|
2192
|
+
let sum = new BigN(0);
|
|
2193
|
+
let sizeInfo = null;
|
|
2194
|
+
try {
|
|
2195
|
+
const _fee = fee;
|
|
2196
|
+
const _feeCustom = feeCustom;
|
|
2197
|
+
const combineFee = combineBitcoinFee(_fee, _feeOptions, _feeCustom);
|
|
2198
|
+
const bitcoinApi = this.#koniState.chainService.getBitcoinApi(chain);
|
|
2199
|
+
let utxos = await getTransferableBitcoinUtxos(bitcoinApi, address);
|
|
2200
|
+
const recipients = [address, to || address];
|
|
2201
|
+
utxos = utxos.sort((a, b) => b.value - a.value);
|
|
2202
|
+
const filteredUtxos = filterUneconomicalUtxos({
|
|
2203
|
+
utxos,
|
|
2204
|
+
feeRate: combineFee.feeRate,
|
|
2205
|
+
recipients,
|
|
2206
|
+
sender: address
|
|
2207
|
+
});
|
|
2208
|
+
for (const utxo of filteredUtxos) {
|
|
2209
|
+
sizeInfo = getSizeInfo({
|
|
2210
|
+
inputLength: neededUtxos.length,
|
|
2211
|
+
sender: address,
|
|
2212
|
+
recipients
|
|
2213
|
+
});
|
|
2214
|
+
const currentValue = new BigN(amount).plus(Math.ceil(sizeInfo.txVBytes * combineFee.feeRate));
|
|
2215
|
+
if (sum.gte(currentValue)) {
|
|
2216
|
+
break;
|
|
2217
|
+
}
|
|
2218
|
+
sum = sum.plus(utxo.value);
|
|
2219
|
+
neededUtxos.push(utxo);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
// re calculate
|
|
2223
|
+
sizeInfo = getSizeInfo({
|
|
2224
|
+
inputLength: neededUtxos.length,
|
|
2225
|
+
sender: address,
|
|
2226
|
+
recipients
|
|
2227
|
+
});
|
|
2228
|
+
if (!sizeInfo) {
|
|
2229
|
+
sizeInfo = getSizeInfo({
|
|
2230
|
+
inputLength: utxos.length || 1,
|
|
2231
|
+
sender: address,
|
|
2232
|
+
recipients
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
estimatedFee = Math.ceil(sizeInfo.txVBytes * combineFee.feeRate).toString();
|
|
2236
|
+
const amountLeft = sum.minus(amount).minus(new BigN(estimatedFee));
|
|
2237
|
+
if (amountLeft.lte(0)) {
|
|
2238
|
+
error = 'Insufficient balance';
|
|
2239
|
+
} else {
|
|
2240
|
+
const senderAddressInfo = getBitcoinAddressInfo(address);
|
|
2241
|
+
const dustLimit = BTC_DUST_AMOUNT[senderAddressInfo.type] || 546;
|
|
2242
|
+
if (amountLeft.lte(dustLimit)) {
|
|
2243
|
+
sizeInfo = getSizeInfo({
|
|
2244
|
+
inputLength: neededUtxos.length,
|
|
2245
|
+
sender: address,
|
|
2246
|
+
recipients: [to || address]
|
|
2247
|
+
});
|
|
2248
|
+
estimatedFee = sum.minus(amount).toString();
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
feeOptions = {
|
|
2252
|
+
...fee,
|
|
2253
|
+
vSize: sizeInfo.txVBytes,
|
|
2254
|
+
estimatedFee
|
|
2255
|
+
};
|
|
2256
|
+
} catch (e) {
|
|
2257
|
+
feeOptions = {
|
|
2258
|
+
...fee,
|
|
2259
|
+
estimatedFee,
|
|
2260
|
+
vSize: 0
|
|
2261
|
+
};
|
|
2262
|
+
error = e.message || e;
|
|
2263
|
+
console.warn('Unable to estimate fee', e);
|
|
2264
|
+
}
|
|
2265
|
+
return {
|
|
2266
|
+
feeOptions: feeOptions,
|
|
2267
|
+
feeType,
|
|
2268
|
+
error,
|
|
2269
|
+
id
|
|
2270
|
+
};
|
|
2271
|
+
};
|
|
2272
|
+
const subscription = combineLatest({
|
|
2273
|
+
freeBalance: freeBalanceSubject,
|
|
2274
|
+
fee: feeSubject
|
|
2275
|
+
}).subscribe({
|
|
2276
|
+
next: ({
|
|
2277
|
+
fee,
|
|
2278
|
+
freeBalance
|
|
2279
|
+
}) => {
|
|
2280
|
+
convertData(freeBalance, fee, _feeOptions, feeCustom).then(cb).catch(console.error);
|
|
2281
|
+
}
|
|
2282
|
+
});
|
|
2283
|
+
const [unsubBalance, freeBalance] = await this.#koniState.balanceService.subscribeBalance(address, chain, token, 'transferable', ExtrinsicType.TRANSFER_BALANCE, data => {
|
|
2284
|
+
freeBalanceSubject.next(data); // Must be called after subscription
|
|
2285
|
+
});
|
|
2286
|
+
|
|
2287
|
+
const fee = await this.#koniState.feeService.subscribeChainFee(id, chain, feeType, data => {
|
|
2288
|
+
feeSubject.next(data); // Must be called after subscription
|
|
2289
|
+
});
|
|
2290
|
+
|
|
2291
|
+
const unsub = () => {
|
|
2292
|
+
subscription.unsubscribe();
|
|
2293
|
+
unsubBalance();
|
|
2294
|
+
this.#koniState.feeService.unsubscribeChainFee(id, chain, feeType);
|
|
2295
|
+
};
|
|
2296
|
+
this.createUnsubscriptionHandle(id, unsub);
|
|
2297
|
+
port.onDisconnect.addListener(() => {
|
|
2298
|
+
this.cancelSubscription(id);
|
|
2299
|
+
});
|
|
2300
|
+
return convertData(freeBalance, fee, _feeOptions, feeCustom);
|
|
2301
|
+
}
|
|
1985
2302
|
async subscribeAddressTransferableBalance({
|
|
1986
2303
|
address,
|
|
1987
2304
|
extrinsicType,
|
|
@@ -2850,6 +3167,7 @@ export default class KoniExtension {
|
|
|
2850
3167
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2851
3168
|
const {
|
|
2852
3169
|
additionalValidator,
|
|
3170
|
+
emitterTransaction,
|
|
2853
3171
|
eventsHandler,
|
|
2854
3172
|
step,
|
|
2855
3173
|
transaction,
|
|
@@ -4640,6 +4958,8 @@ export default class KoniExtension {
|
|
|
4640
4958
|
return await this.updateAssetSetting(request);
|
|
4641
4959
|
case 'pri(transfer.subscribe)':
|
|
4642
4960
|
return this.subscribeMaxTransferable(request, id, port);
|
|
4961
|
+
case 'pri(transfer.confirmation.subscribe)':
|
|
4962
|
+
return this.subscribeTransferableWhenConfirmation(request, id, port);
|
|
4643
4963
|
case 'pri(freeBalance.get)':
|
|
4644
4964
|
return this.getAddressTransferableBalance(request);
|
|
4645
4965
|
case 'pri(freeBalance.subscribe)':
|
|
@@ -4658,6 +4978,10 @@ export default class KoniExtension {
|
|
|
4658
4978
|
/// Transfer
|
|
4659
4979
|
case 'pri(accounts.transfer)':
|
|
4660
4980
|
return await this.makeTransfer(request);
|
|
4981
|
+
case 'pri(accounts.bitcoin.dapp.transfer.confirmation)':
|
|
4982
|
+
return await this.makeBitcoinDappTransferConfirmation(request);
|
|
4983
|
+
case 'pri(accounts.psbt.transfer.confirmation)':
|
|
4984
|
+
return await this.makePsbtTransferAfterConfirmation(request);
|
|
4661
4985
|
case 'pri(accounts.crossChainTransfer)':
|
|
4662
4986
|
return await this.makeCrossChainTransfer(request);
|
|
4663
4987
|
case 'pri(accounts.getOptimalTransferProcess)':
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="chrome" />
|
|
2
2
|
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs';
|
|
3
3
|
import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
|
|
4
|
-
import { AddTokenRequestExternal, AmountData, ApiMap, AuthRequestV2, ChainStakingMetadata, ConfirmationsQueue, ConfirmationsQueueBitcoin, ConfirmationsQueueCardano, ConfirmationsQueueTon, CrowdloanItem, CrowdloanJson, EvmSendTransactionParams, ExternalRequestPromise, MantaPayConfig, MantaPaySyncState, NftCollection, NftItem, NftJson, NominatorMetadata, RequestAccountExportPrivateKey, RequestCardanoSignData, RequestCardanoSignTransaction, RequestConfirmationComplete, RequestConfirmationCompleteBitcoin, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon, RequestCrowdloanContributions, RequestSettingsType, ResponseAccountExportPrivateKey, ResponseCardanoSignData, ResponseCardanoSignTransaction, ServiceInfo, SingleModeJson, StakingItem, StakingJson, StakingRewardItem, StakingRewardJson, StakingType, UiSettings } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
|
+
import { AddTokenRequestExternal, AmountData, ApiMap, AuthRequestV2, BitcoinSendTransactionParams, BitcoinSignMessageParams, BitcoinSignMessageResult, BitcoinSignPsbtParams, BitcoinSignPsbtResult, ChainStakingMetadata, ConfirmationsQueue, ConfirmationsQueueBitcoin, ConfirmationsQueueCardano, ConfirmationsQueueTon, CrowdloanItem, CrowdloanJson, EvmSendTransactionParams, ExternalRequestPromise, MantaPayConfig, MantaPaySyncState, NftCollection, NftItem, NftJson, NominatorMetadata, RequestAccountExportPrivateKey, RequestCardanoSignData, RequestCardanoSignTransaction, RequestConfirmationComplete, RequestConfirmationCompleteBitcoin, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon, RequestCrowdloanContributions, RequestSettingsType, ResponseAccountExportPrivateKey, ResponseCardanoSignData, ResponseCardanoSignTransaction, ServiceInfo, SingleModeJson, StakingItem, StakingJson, StakingRewardItem, StakingRewardJson, StakingType, UiSettings } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
5
|
import { RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestSign, ResponseRpcListProviders, ResponseSigning } from '@subwallet/extension-base/background/types';
|
|
6
6
|
import { EnvConfig } from '@subwallet/extension-base/constants';
|
|
7
7
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
@@ -222,6 +222,9 @@ export default class KoniState {
|
|
|
222
222
|
cardanoSignData(id: string, url: string, params: RequestCardanoSignData, currentAddress: string): Promise<ResponseCardanoSignData>;
|
|
223
223
|
cardanoSignTx(id: string, url: string, param: RequestCardanoSignTransaction, currentAddress: string): Promise<ResponseCardanoSignTransaction>;
|
|
224
224
|
cardanoSubmitTx(id: string, url: string, txHex: string): Promise<string>;
|
|
225
|
+
bitcoinSign(id: string, url: string, method: string, params: BitcoinSignMessageParams): Promise<BitcoinSignMessageResult>;
|
|
226
|
+
bitcoinSignPspt(id: string, url: string, params: BitcoinSignPsbtParams): Promise<BitcoinSignPsbtResult>;
|
|
227
|
+
bitcoinSendTransaction(id: string, url: string, transactionParams: BitcoinSendTransactionParams): Promise<string | undefined>;
|
|
225
228
|
getConfirmationsQueueSubject(): BehaviorSubject<ConfirmationsQueue>;
|
|
226
229
|
getConfirmationsQueueSubjectTon(): BehaviorSubject<ConfirmationsQueueTon>;
|
|
227
230
|
getConfirmationsQueueSubjectCardano(): BehaviorSubject<ConfirmationsQueueCardano>;
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs';
|
|
5
|
+
import { BitcoinProviderError } from '@subwallet/extension-base/background/errors/BitcoinProviderError';
|
|
5
6
|
import { CardanoProviderError } from '@subwallet/extension-base/background/errors/CardanoProviderError';
|
|
6
7
|
import { EvmProviderError } from '@subwallet/extension-base/background/errors/EvmProviderError';
|
|
7
8
|
import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
|
|
8
9
|
import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
|
|
9
|
-
import { APIItemState, CardanoProviderErrorType, ChainType, EvmProviderErrorType, ExternalRequestPromiseStatus, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
10
|
+
import { APIItemState, BitcoinProviderErrorType, CardanoProviderErrorType, ChainType, EvmProviderErrorType, ExternalRequestPromiseStatus, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
10
11
|
import { BACKEND_API_URL, BACKEND_PRICE_HISTORY_URL, MANTA_PAY_BALANCE_INTERVAL, REMIND_EXPORT_ACCOUNT } from '@subwallet/extension-base/constants';
|
|
11
|
-
import { convertErrorFormat, generateValidationProcess, validationAuthCardanoMiddleware, validationAuthMiddleware, validationAuthWCMiddleware, validationCardanoSignDataMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware, validationEvmSignMessageMiddleware } from '@subwallet/extension-base/core/logic-validation';
|
|
12
|
+
import { convertErrorFormat, generateValidationProcess, validationAuthCardanoMiddleware, validationAuthMiddleware, validationAuthWCMiddleware, validationBitcoinConnectMiddleware, validationBitcoinSendTransactionMiddleware, validationBitcoinSignMessageMiddleware, validationBitcoinSignPsbtMiddleware, validationCardanoSignDataMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware, validationEvmSignMessageMiddleware } from '@subwallet/extension-base/core/logic-validation';
|
|
12
13
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
13
14
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
14
15
|
import BuyService from '@subwallet/extension-base/services/buy-service';
|
|
@@ -45,6 +46,8 @@ import { convertCardanoHexToBech32, validateAddressNetwork } from '@subwallet/ex
|
|
|
45
46
|
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
46
47
|
import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
|
|
47
48
|
import { keyring } from '@subwallet/ui-keyring';
|
|
49
|
+
import BigN from 'bignumber.js';
|
|
50
|
+
import * as bitcoin from 'bitcoinjs-lib';
|
|
48
51
|
import BN from 'bn.js';
|
|
49
52
|
import { t } from 'i18next';
|
|
50
53
|
import { Subject } from 'rxjs';
|
|
@@ -104,7 +107,7 @@ export default class KoniState {
|
|
|
104
107
|
this.chainService = new ChainService(this.dbService, this.eventService);
|
|
105
108
|
this.subscanService = SubscanService.getInstance();
|
|
106
109
|
this.settingService = new SettingService();
|
|
107
|
-
this.requestService = new RequestService(this.chainService, this.settingService, this.keyringService, this.
|
|
110
|
+
this.requestService = new RequestService(this.chainService, this.settingService, this.keyringService, this.transactionService);
|
|
108
111
|
this.priceService = new PriceService(this.dbService, this.eventService, this.chainService);
|
|
109
112
|
this.balanceService = new BalanceService(this);
|
|
110
113
|
this.historyService = new HistoryService(this.dbService, this.chainService, this.eventService, this.keyringService, this.subscanService);
|
|
@@ -1021,6 +1024,8 @@ export default class KoniState {
|
|
|
1021
1024
|
});
|
|
1022
1025
|
});
|
|
1023
1026
|
}
|
|
1027
|
+
|
|
1028
|
+
// Cardano
|
|
1024
1029
|
async cardanoGetBalance(id, url, address) {
|
|
1025
1030
|
const authInfoMap = await this.getAuthList();
|
|
1026
1031
|
const authInfo = authInfoMap[stripUrl(url)];
|
|
@@ -1241,6 +1246,186 @@ export default class KoniState {
|
|
|
1241
1246
|
const cardanoApi = this.chainService.getCardanoApi(networkKey);
|
|
1242
1247
|
return await cardanoApi.sendCardanoTxReturnHash(txHex);
|
|
1243
1248
|
}
|
|
1249
|
+
|
|
1250
|
+
// Bitcoin
|
|
1251
|
+
async bitcoinSign(id, url, method, params) {
|
|
1252
|
+
const {
|
|
1253
|
+
address,
|
|
1254
|
+
message
|
|
1255
|
+
} = params;
|
|
1256
|
+
const payloadValidation = {
|
|
1257
|
+
address,
|
|
1258
|
+
type: 'bitcoin',
|
|
1259
|
+
payloadAfterValidated: message,
|
|
1260
|
+
errors: [],
|
|
1261
|
+
networkKey: ''
|
|
1262
|
+
};
|
|
1263
|
+
const validationSteps = [validationAuthMiddleware, validationBitcoinSignMessageMiddleware];
|
|
1264
|
+
const result = await generateValidationProcess(this, url, payloadValidation, validationSteps);
|
|
1265
|
+
const errorsFormated = convertErrorFormat(result.errors);
|
|
1266
|
+
const payloadAfterValidated = {
|
|
1267
|
+
...result.payloadAfterValidated,
|
|
1268
|
+
errors: errorsFormated,
|
|
1269
|
+
id
|
|
1270
|
+
};
|
|
1271
|
+
return this.requestService.addConfirmationBitcoin(id, url, 'bitcoinSignatureRequest', payloadAfterValidated, {}).then(({
|
|
1272
|
+
isApproved,
|
|
1273
|
+
payload
|
|
1274
|
+
}) => {
|
|
1275
|
+
if (isApproved) {
|
|
1276
|
+
if (payload) {
|
|
1277
|
+
return payload;
|
|
1278
|
+
} else {
|
|
1279
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, t('Not found signature'));
|
|
1280
|
+
}
|
|
1281
|
+
} else {
|
|
1282
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.USER_REJECTED_REQUEST);
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
async bitcoinSignPspt(id, url, params) {
|
|
1287
|
+
const {
|
|
1288
|
+
address,
|
|
1289
|
+
network,
|
|
1290
|
+
psbt
|
|
1291
|
+
} = params;
|
|
1292
|
+
const payloadValidation = {
|
|
1293
|
+
address,
|
|
1294
|
+
type: 'bitcoin',
|
|
1295
|
+
payloadAfterValidated: params,
|
|
1296
|
+
errors: [],
|
|
1297
|
+
networkKey: network === 'mainnet' ? 'bitcoin' : 'bitcoinTestnet'
|
|
1298
|
+
};
|
|
1299
|
+
const validationSteps = [validationAuthMiddleware, validationBitcoinConnectMiddleware, validationBitcoinSignPsbtMiddleware];
|
|
1300
|
+
const result = await generateValidationProcess(this, url, payloadValidation, validationSteps);
|
|
1301
|
+
const errorsFormated = convertErrorFormat(result.errors);
|
|
1302
|
+
const payloadAfterValidated = {
|
|
1303
|
+
...result.payloadAfterValidated,
|
|
1304
|
+
errors: errorsFormated
|
|
1305
|
+
};
|
|
1306
|
+
const network_ = network === 'mainnet' ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
|
|
1307
|
+
const psbtGenerate = bitcoin.Psbt.fromHex(psbt, {
|
|
1308
|
+
network: network_
|
|
1309
|
+
});
|
|
1310
|
+
const isExistedInput = (inputs, address) => inputs.findIndex(({
|
|
1311
|
+
address: address_
|
|
1312
|
+
}) => isSameAddress(address, address_ || ''));
|
|
1313
|
+
let to = '';
|
|
1314
|
+
const tokenInfo = this.getNativeTokenInfo(result.networkKey);
|
|
1315
|
+
let value = new BigN(0);
|
|
1316
|
+
const totalBalance = await this.balanceService.getTotalBalance(address, result.networkKey, tokenInfo.slug);
|
|
1317
|
+
let inputAmount = new BigN(0);
|
|
1318
|
+
const psbtInputData = psbtGenerate.data.inputs.reduce((inputs, {
|
|
1319
|
+
nonWitnessUtxo,
|
|
1320
|
+
witnessUtxo
|
|
1321
|
+
}, inputIndex) => {
|
|
1322
|
+
let inputData = null;
|
|
1323
|
+
if (witnessUtxo) {
|
|
1324
|
+
inputData = {
|
|
1325
|
+
address: bitcoin.address.fromOutputScript(witnessUtxo === null || witnessUtxo === void 0 ? void 0 : witnessUtxo.script, network_),
|
|
1326
|
+
amount: witnessUtxo.value.toString()
|
|
1327
|
+
};
|
|
1328
|
+
} else if (nonWitnessUtxo) {
|
|
1329
|
+
const txin = psbtGenerate.txInputs[inputIndex];
|
|
1330
|
+
const txout = bitcoin.Transaction.fromBuffer(nonWitnessUtxo).outs[txin.index];
|
|
1331
|
+
inputData = {
|
|
1332
|
+
address: bitcoin.address.fromOutputScript(txout.script, network_),
|
|
1333
|
+
amount: txout.value.toString()
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
if (inputData) {
|
|
1337
|
+
inputs.push(inputData);
|
|
1338
|
+
if (isSameAddress(address, inputData.address || '')) {
|
|
1339
|
+
inputAmount = inputAmount.plus(new BigN(inputData.amount || '0'));
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
return inputs;
|
|
1343
|
+
}, []);
|
|
1344
|
+
if (new BigN(totalBalance.value).lt(inputAmount)) {
|
|
1345
|
+
payloadAfterValidated.errors = [{
|
|
1346
|
+
message: t('Insufficient balance'),
|
|
1347
|
+
name: t('Unable to sign transaction')
|
|
1348
|
+
}];
|
|
1349
|
+
}
|
|
1350
|
+
const psbtOutputData = psbtGenerate.txOutputs.map(output => {
|
|
1351
|
+
let address = '';
|
|
1352
|
+
try {
|
|
1353
|
+
address = output.address || bitcoin.address.fromOutputScript(output.script, network_);
|
|
1354
|
+
} catch (e) {
|
|
1355
|
+
if (output.script.includes(bitcoin.opcodes.OP_RETURN)) {
|
|
1356
|
+
address = 'OP_RETURN';
|
|
1357
|
+
} else {
|
|
1358
|
+
address = 'Unknown';
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
if (isExistedInput(psbtInputData, address) === -1) {
|
|
1362
|
+
to = address;
|
|
1363
|
+
value = value.plus(new BigN(output.value));
|
|
1364
|
+
}
|
|
1365
|
+
return {
|
|
1366
|
+
address,
|
|
1367
|
+
amount: output.value.toString()
|
|
1368
|
+
};
|
|
1369
|
+
});
|
|
1370
|
+
payloadAfterValidated.payload = {
|
|
1371
|
+
...payloadAfterValidated.payload,
|
|
1372
|
+
psbt,
|
|
1373
|
+
tokenSlug: tokenInfo.slug,
|
|
1374
|
+
value: value.toString(),
|
|
1375
|
+
to,
|
|
1376
|
+
txInput: psbtInputData,
|
|
1377
|
+
txOutput: psbtOutputData
|
|
1378
|
+
};
|
|
1379
|
+
return this.requestService.addConfirmationBitcoin(id, url, 'bitcoinSignPsbtRequest', payloadAfterValidated, {}).then(({
|
|
1380
|
+
isApproved,
|
|
1381
|
+
payload
|
|
1382
|
+
}) => {
|
|
1383
|
+
if (isApproved) {
|
|
1384
|
+
if (payload) {
|
|
1385
|
+
return payload;
|
|
1386
|
+
} else {
|
|
1387
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, t('Not found signature'));
|
|
1388
|
+
}
|
|
1389
|
+
} else {
|
|
1390
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.USER_REJECTED_REQUEST);
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
async bitcoinSendTransaction(id, url, transactionParams) {
|
|
1395
|
+
const payloadValidation = {
|
|
1396
|
+
address: transactionParams.account,
|
|
1397
|
+
type: 'bitcoin',
|
|
1398
|
+
payloadAfterValidated: transactionParams,
|
|
1399
|
+
errors: [],
|
|
1400
|
+
networkKey: transactionParams.network === 'mainnet' ? 'bitcoin' : 'bitcoinTestnet'
|
|
1401
|
+
};
|
|
1402
|
+
const validationSteps = [validationAuthMiddleware, validationBitcoinConnectMiddleware, validationBitcoinSendTransactionMiddleware];
|
|
1403
|
+
const result = await generateValidationProcess(this, url, payloadValidation, validationSteps);
|
|
1404
|
+
const errorsFormated = convertErrorFormat(result.errors);
|
|
1405
|
+
const requestPayload = {
|
|
1406
|
+
...result.payloadAfterValidated,
|
|
1407
|
+
hashPayload: JSON.stringify(result.payloadAfterValidated),
|
|
1408
|
+
from: transactionParams.account,
|
|
1409
|
+
id,
|
|
1410
|
+
errors: errorsFormated
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
// Custom handle this instead of general handler transaction
|
|
1414
|
+
return this.requestService.addConfirmationBitcoin(id, url, 'bitcoinSendTransactionRequestAfterConfirmation', requestPayload, {}).then(({
|
|
1415
|
+
isApproved,
|
|
1416
|
+
payload
|
|
1417
|
+
}) => {
|
|
1418
|
+
if (isApproved) {
|
|
1419
|
+
if (payload) {
|
|
1420
|
+
return payload;
|
|
1421
|
+
} else {
|
|
1422
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, t('Not found signature'));
|
|
1423
|
+
}
|
|
1424
|
+
} else {
|
|
1425
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.USER_REJECTED_REQUEST);
|
|
1426
|
+
}
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1244
1429
|
getConfirmationsQueueSubject() {
|
|
1245
1430
|
return this.requestService.confirmationsQueueSubject;
|
|
1246
1431
|
}
|
|
@@ -1480,9 +1665,9 @@ export default class KoniState {
|
|
|
1480
1665
|
this.eventService.emit('general.start', true);
|
|
1481
1666
|
|
|
1482
1667
|
// Complete starting
|
|
1483
|
-
starting.resolve();
|
|
1484
1668
|
this.waitStarting = null;
|
|
1485
1669
|
this.generalStatus = ServiceStatus.STARTED;
|
|
1670
|
+
starting.resolve();
|
|
1486
1671
|
}
|
|
1487
1672
|
async _startFull() {
|
|
1488
1673
|
// Continue wait existed starting process
|