@subwallet/extension-base 1.3.41-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.
Files changed (219) hide show
  1. package/background/KoniTypes.d.ts +134 -5
  2. package/background/KoniTypes.js +18 -0
  3. package/background/errors/BitcoinProviderError.d.ts +6 -0
  4. package/background/errors/BitcoinProviderError.js +47 -0
  5. package/background/types.d.ts +1 -1
  6. package/cjs/background/KoniTypes.js +20 -1
  7. package/cjs/background/errors/BitcoinProviderError.js +54 -0
  8. package/cjs/constants/bitcoin.js +22 -0
  9. package/cjs/constants/index.js +16 -1
  10. package/cjs/core/logic-validation/recipientAddress.js +9 -0
  11. package/cjs/core/logic-validation/request.js +316 -3
  12. package/cjs/core/logic-validation/transfer.js +25 -5
  13. package/cjs/core/types.js +1 -0
  14. package/cjs/core/utils.js +15 -1
  15. package/cjs/koni/background/handlers/Extension.js +477 -93
  16. package/cjs/koni/background/handlers/State.js +249 -16
  17. package/cjs/koni/background/handlers/Tabs.js +119 -6
  18. package/cjs/packageInfo.js +1 -1
  19. package/cjs/page/bitcoin/index.js +67 -0
  20. package/cjs/page/index.js +5 -0
  21. package/cjs/services/balance-service/helpers/subscribe/bitcoin.js +94 -0
  22. package/cjs/services/balance-service/helpers/subscribe/index.js +19 -7
  23. package/cjs/services/balance-service/index.js +32 -4
  24. package/cjs/services/balance-service/transfer/bitcoin-transfer.js +119 -0
  25. package/cjs/services/balance-service/transfer/token.js +2 -0
  26. package/cjs/services/base/types.js +2 -0
  27. package/cjs/services/buy-service/index.js +17 -2
  28. package/cjs/services/chain-service/constants.js +14 -3
  29. package/cjs/services/chain-service/handler/bitcoin/BitcoinApi.js +105 -0
  30. package/cjs/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +78 -0
  31. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +371 -0
  32. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +19 -0
  33. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +368 -0
  34. package/cjs/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +302 -0
  35. package/cjs/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  36. package/cjs/services/chain-service/index.js +27 -3
  37. package/cjs/services/chain-service/utils/index.js +57 -4
  38. package/cjs/services/chain-service/utils/patch.js +1 -1
  39. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +27 -5
  40. package/cjs/services/event-service/index.js +4 -0
  41. package/cjs/services/fee-service/service.js +8 -3
  42. package/cjs/services/hiro-service/index.js +96 -0
  43. package/cjs/services/hiro-service/utils/index.js +85 -0
  44. package/cjs/services/history-service/bitcoin-history.js +58 -0
  45. package/cjs/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  46. package/cjs/services/history-service/index.js +41 -3
  47. package/cjs/services/keyring-service/context/handlers/Derive.js +1 -1
  48. package/cjs/services/keyring-service/context/handlers/Migration.js +2 -2
  49. package/cjs/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  50. package/cjs/services/migration-service/scripts/MigrateNewUnifiedAccount.js +29 -0
  51. package/cjs/services/migration-service/scripts/index.js +3 -1
  52. package/cjs/services/request-service/handler/AuthRequestHandler.js +18 -0
  53. package/cjs/services/request-service/handler/BitcoinRequestHandler.js +427 -0
  54. package/cjs/services/request-service/index.js +29 -3
  55. package/cjs/services/rune-service/index.js +105 -0
  56. package/cjs/services/transaction-service/helpers/index.js +7 -1
  57. package/cjs/services/transaction-service/index.js +206 -16
  58. package/cjs/services/transaction-service/utils.js +6 -3
  59. package/cjs/strategy/api-request-strategy/context/base.js +31 -0
  60. package/cjs/strategy/api-request-strategy/index.js +90 -0
  61. package/cjs/strategy/api-request-strategy/types.js +1 -0
  62. package/cjs/strategy/api-request-strategy/utils/index.js +33 -0
  63. package/cjs/types/account/info/keyring.js +1 -1
  64. package/cjs/types/bitcoin.js +24 -0
  65. package/cjs/types/fee/bitcoin.js +1 -0
  66. package/cjs/types/fee/index.js +11 -0
  67. package/cjs/types/index.js +11 -0
  68. package/cjs/utils/account/analyze.js +3 -3
  69. package/cjs/utils/account/common.js +16 -6
  70. package/cjs/utils/account/derive/info/solo.js +68 -19
  71. package/cjs/utils/account/derive/info/unified.js +2 -0
  72. package/cjs/utils/account/derive/validate.js +70 -2
  73. package/cjs/utils/account/transform.js +11 -5
  74. package/cjs/utils/auth.js +2 -1
  75. package/cjs/utils/bitcoin/common.js +98 -0
  76. package/cjs/utils/bitcoin/fee.js +21 -0
  77. package/cjs/utils/bitcoin/index.js +38 -0
  78. package/cjs/utils/bitcoin/utxo-management.js +281 -0
  79. package/cjs/utils/fee/transfer.js +48 -0
  80. package/cjs/utils/index.js +15 -1
  81. package/constants/bitcoin.d.ts +3 -0
  82. package/constants/bitcoin.js +13 -0
  83. package/constants/index.d.ts +2 -0
  84. package/constants/index.js +3 -1
  85. package/core/logic-validation/recipientAddress.js +10 -1
  86. package/core/logic-validation/request.d.ts +6 -2
  87. package/core/logic-validation/request.js +309 -3
  88. package/core/logic-validation/transfer.d.ts +2 -2
  89. package/core/logic-validation/transfer.js +27 -7
  90. package/core/types.d.ts +1 -0
  91. package/core/types.js +1 -0
  92. package/core/utils.d.ts +1 -0
  93. package/core/utils.js +15 -2
  94. package/koni/background/handlers/Extension.d.ts +5 -0
  95. package/koni/background/handlers/Extension.js +387 -9
  96. package/koni/background/handlers/State.d.ts +10 -3
  97. package/koni/background/handlers/State.js +240 -15
  98. package/koni/background/handlers/Tabs.d.ts +7 -2
  99. package/koni/background/handlers/Tabs.js +119 -9
  100. package/package.json +149 -8
  101. package/packageInfo.js +1 -1
  102. package/page/bitcoin/index.d.ts +17 -0
  103. package/page/bitcoin/index.js +60 -0
  104. package/page/index.d.ts +2 -1
  105. package/page/index.js +4 -0
  106. package/services/balance-service/helpers/subscribe/bitcoin.d.ts +2 -0
  107. package/services/balance-service/helpers/subscribe/bitcoin.js +87 -0
  108. package/services/balance-service/helpers/subscribe/index.d.ts +2 -2
  109. package/services/balance-service/helpers/subscribe/index.js +20 -8
  110. package/services/balance-service/index.d.ts +2 -0
  111. package/services/balance-service/index.js +32 -4
  112. package/services/balance-service/transfer/bitcoin-transfer.d.ts +14 -0
  113. package/services/balance-service/transfer/bitcoin-transfer.js +112 -0
  114. package/services/balance-service/transfer/cardano-transfer.d.ts +2 -0
  115. package/services/balance-service/transfer/token.js +2 -0
  116. package/services/base/types.d.ts +2 -0
  117. package/services/base/types.js +2 -0
  118. package/services/buy-service/index.js +17 -2
  119. package/services/chain-service/constants.d.ts +6 -0
  120. package/services/chain-service/constants.js +8 -2
  121. package/services/chain-service/handler/bitcoin/BitcoinApi.d.ts +31 -0
  122. package/services/chain-service/handler/bitcoin/BitcoinApi.js +98 -0
  123. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.d.ts +16 -0
  124. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +70 -0
  125. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.d.ts +28 -0
  126. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +362 -0
  127. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.d.ts +2 -0
  128. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +5 -0
  129. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.d.ts +28 -0
  130. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +359 -0
  131. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.d.ts +28 -0
  132. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +293 -0
  133. package/services/chain-service/handler/bitcoin/strategy/types.d.ts +291 -0
  134. package/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  135. package/services/chain-service/index.d.ts +3 -0
  136. package/services/chain-service/index.js +31 -5
  137. package/services/chain-service/types.d.ts +20 -0
  138. package/services/chain-service/utils/index.d.ts +4 -0
  139. package/services/chain-service/utils/index.js +50 -4
  140. package/services/chain-service/utils/patch.js +1 -1
  141. package/services/earning-service/handlers/native-staking/para-chain.js +27 -5
  142. package/services/event-service/index.d.ts +3 -0
  143. package/services/event-service/index.js +4 -0
  144. package/services/event-service/types.d.ts +3 -0
  145. package/services/fee-service/service.js +8 -3
  146. package/services/hiro-service/index.d.ts +17 -0
  147. package/services/hiro-service/index.js +88 -0
  148. package/services/hiro-service/utils/index.d.ts +6 -0
  149. package/services/hiro-service/utils/index.js +72 -0
  150. package/services/history-service/bitcoin-history.d.ts +4 -0
  151. package/services/history-service/bitcoin-history.js +52 -0
  152. package/services/history-service/helpers/recoverHistoryStatus.d.ts +3 -1
  153. package/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  154. package/services/history-service/index.d.ts +1 -0
  155. package/services/history-service/index.js +42 -4
  156. package/services/keyring-service/context/handlers/Derive.js +2 -2
  157. package/services/keyring-service/context/handlers/Migration.js +2 -2
  158. package/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  159. package/services/migration-service/scripts/MigrateNewUnifiedAccount.d.ts +4 -0
  160. package/services/migration-service/scripts/MigrateNewUnifiedAccount.js +21 -0
  161. package/services/migration-service/scripts/index.js +3 -1
  162. package/services/request-service/handler/AuthRequestHandler.js +19 -1
  163. package/services/request-service/handler/BitcoinRequestHandler.d.ts +22 -0
  164. package/services/request-service/handler/BitcoinRequestHandler.js +414 -0
  165. package/services/request-service/index.d.ts +8 -2
  166. package/services/request-service/index.js +25 -3
  167. package/services/rune-service/index.d.ts +17 -0
  168. package/services/rune-service/index.js +97 -0
  169. package/services/transaction-service/helpers/index.d.ts +3 -1
  170. package/services/transaction-service/helpers/index.js +5 -0
  171. package/services/transaction-service/index.d.ts +4 -5
  172. package/services/transaction-service/index.js +205 -17
  173. package/services/transaction-service/types.d.ts +13 -2
  174. package/services/transaction-service/utils.js +7 -4
  175. package/strategy/api-request-strategy/context/base.d.ts +15 -0
  176. package/strategy/api-request-strategy/context/base.js +24 -0
  177. package/strategy/api-request-strategy/index.d.ts +15 -0
  178. package/strategy/api-request-strategy/index.js +83 -0
  179. package/strategy/api-request-strategy/types.d.ts +22 -0
  180. package/strategy/api-request-strategy/types.js +1 -0
  181. package/strategy/api-request-strategy/utils/index.d.ts +2 -0
  182. package/strategy/api-request-strategy/utils/index.js +23 -0
  183. package/types/account/info/keyring.d.ts +1 -1
  184. package/types/account/info/keyring.js +1 -1
  185. package/types/balance/index.d.ts +4 -1
  186. package/types/balance/transfer.d.ts +19 -0
  187. package/types/bitcoin.d.ts +93 -0
  188. package/types/bitcoin.js +17 -0
  189. package/types/buy.d.ts +1 -1
  190. package/types/fee/base.d.ts +4 -1
  191. package/types/fee/bitcoin.d.ts +18 -0
  192. package/types/fee/bitcoin.js +1 -0
  193. package/types/fee/index.d.ts +1 -0
  194. package/types/fee/index.js +2 -1
  195. package/types/fee/subscription.d.ts +4 -3
  196. package/types/index.d.ts +1 -0
  197. package/types/index.js +1 -0
  198. package/utils/account/analyze.js +4 -4
  199. package/utils/account/common.d.ts +7 -8
  200. package/utils/account/common.js +16 -6
  201. package/utils/account/derive/info/solo.js +70 -21
  202. package/utils/account/derive/info/unified.js +2 -0
  203. package/utils/account/derive/validate.d.ts +1 -0
  204. package/utils/account/derive/validate.js +68 -1
  205. package/utils/account/transform.d.ts +1 -1
  206. package/utils/account/transform.js +11 -5
  207. package/utils/auth.js +3 -2
  208. package/utils/bitcoin/common.d.ts +22 -0
  209. package/utils/bitcoin/common.js +88 -0
  210. package/utils/bitcoin/fee.d.ts +2 -0
  211. package/utils/bitcoin/fee.js +14 -0
  212. package/utils/bitcoin/index.d.ts +3 -0
  213. package/utils/bitcoin/index.js +6 -0
  214. package/utils/bitcoin/utxo-management.d.ts +33 -0
  215. package/utils/bitcoin/utxo-management.js +266 -0
  216. package/utils/fee/transfer.d.ts +3 -1
  217. package/utils/fee/transfer.js +47 -1
  218. package/utils/index.d.ts +1 -0
  219. package/utils/index.js +6 -3
@@ -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';
@@ -87,6 +90,7 @@ export default class KoniState {
87
90
  generalStatus = ServiceStatus.INITIALIZING;
88
91
  waitSleeping = null;
89
92
  waitStarting = null;
93
+ waitStartingFull = null;
90
94
  constructor(providers = {}) {
91
95
  // Init subwallet api sdk
92
96
  subwalletApiSdk.init({
@@ -97,11 +101,13 @@ export default class KoniState {
97
101
  this.eventService = new EventService();
98
102
  this.dbService = new DatabaseService(this.eventService);
99
103
  this.keyringService = new KeyringService(this);
104
+ this.feeService = new FeeService(this);
105
+ this.transactionService = new TransactionService(this);
100
106
  this.notificationService = new NotificationService();
101
107
  this.chainService = new ChainService(this.dbService, this.eventService);
102
108
  this.subscanService = SubscanService.getInstance();
103
109
  this.settingService = new SettingService();
104
- this.requestService = new RequestService(this.chainService, this.settingService, this.keyringService);
110
+ this.requestService = new RequestService(this.chainService, this.settingService, this.keyringService, this.transactionService);
105
111
  this.priceService = new PriceService(this.dbService, this.eventService, this.chainService);
106
112
  this.balanceService = new BalanceService(this);
107
113
  this.historyService = new HistoryService(this.dbService, this.chainService, this.eventService, this.keyringService, this.subscanService);
@@ -111,9 +117,7 @@ export default class KoniState {
111
117
  this.campaignService = new CampaignService(this);
112
118
  this.mktCampaignService = new MktCampaignService(this);
113
119
  this.buyService = new BuyService(this);
114
- this.transactionService = new TransactionService(this);
115
120
  this.earningService = new EarningService(this);
116
- this.feeService = new FeeService(this);
117
121
  this.swapService = new SwapService(this);
118
122
  this.inappNotificationService = new InappNotificationService(this.dbService, this.keyringService, this.eventService, this.chainService);
119
123
  this.chainOnlineService = new ChainOnlineService(this.chainService, this.settingService, this.eventService, this.dbService);
@@ -123,7 +127,9 @@ export default class KoniState {
123
127
 
124
128
  // Init state
125
129
  if (targetIsWeb) {
126
- this.init().catch(console.error);
130
+ this.init().then(() => {
131
+ this.wakeup(true).catch(console.error);
132
+ }).catch(console.error);
127
133
  }
128
134
  }
129
135
 
@@ -218,7 +224,8 @@ export default class KoniState {
218
224
  await this.earningService.init();
219
225
  await this.swapService.init();
220
226
  await this.inappNotificationService.init();
221
- this.onReady();
227
+
228
+ // this.onReady();
222
229
  this.onAccountAdd();
223
230
  this.onAccountRemove();
224
231
 
@@ -230,6 +237,9 @@ export default class KoniState {
230
237
  this.chainService.subscribeChainInfoMap().subscribe(() => {
231
238
  this.afterChainServiceInit();
232
239
  });
240
+
241
+ // Mark app is ready
242
+ this.eventService.emit('general.init', true);
233
243
  }
234
244
  async initMantaPay(password) {
235
245
  var _this$chainService, _this$chainService$ma;
@@ -253,11 +263,6 @@ export default class KoniState {
253
263
  this.mantaPayConfigSubject.next(data);
254
264
  });
255
265
  }
256
- onReady() {
257
- // Todo: Need optimize in the future to, only run important services onetime to save resources
258
- // Todo: If optimize must check activity of web-runner of mobile
259
- this._start().catch(console.error);
260
- }
261
266
  updateKeyringState(isReady = true, callback) {
262
267
  this.keyringService.updateKeyringState(isReady);
263
268
  callback && callback();
@@ -740,6 +745,9 @@ export default class KoniState {
740
745
  getCardanoApi(networkKey) {
741
746
  return this.chainService.getCardanoApi(networkKey);
742
747
  }
748
+ getBitcoinApi(networkKey) {
749
+ return this.chainService.getBitcoinApi(networkKey);
750
+ }
743
751
  getApiMap() {
744
752
  return {
745
753
  substrate: this.chainService.getSubstrateApiMap(),
@@ -1016,6 +1024,8 @@ export default class KoniState {
1016
1024
  });
1017
1025
  });
1018
1026
  }
1027
+
1028
+ // Cardano
1019
1029
  async cardanoGetBalance(id, url, address) {
1020
1030
  const authInfoMap = await this.getAuthList();
1021
1031
  const authInfo = authInfoMap[stripUrl(url)];
@@ -1236,6 +1246,186 @@ export default class KoniState {
1236
1246
  const cardanoApi = this.chainService.getCardanoApi(networkKey);
1237
1247
  return await cardanoApi.sendCardanoTxReturnHash(txHex);
1238
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
+ }
1239
1429
  getConfirmationsQueueSubject() {
1240
1430
  return this.requestService.confirmationsQueueSubject;
1241
1431
  }
@@ -1245,6 +1435,9 @@ export default class KoniState {
1245
1435
  getConfirmationsQueueSubjectCardano() {
1246
1436
  return this.requestService.confirmationsQueueSubjectCardano;
1247
1437
  }
1438
+ getConfirmationsQueueSubjectBitcoin() {
1439
+ return this.requestService.confirmationsQueueSubjectBitcoin;
1440
+ }
1248
1441
  async completeConfirmation(request) {
1249
1442
  return await this.requestService.completeConfirmation(request);
1250
1443
  }
@@ -1254,6 +1447,9 @@ export default class KoniState {
1254
1447
  async completeConfirmationCardano(request) {
1255
1448
  return await this.requestService.completeConfirmationCardano(request);
1256
1449
  }
1450
+ async completeConfirmationBitcoin(request) {
1451
+ return await this.requestService.completeConfirmationBitcoin(request);
1452
+ }
1257
1453
  async onMV3Update() {
1258
1454
  const migrationStatus = await SWStorage.instance.getItem('mv3_migration');
1259
1455
  if (!migrationStatus || migrationStatus !== 'done') {
@@ -1404,8 +1600,12 @@ export default class KoniState {
1404
1600
  });
1405
1601
  }
1406
1602
  async sleep() {
1603
+ // Wait for app initialized before sleep
1604
+ await this.eventService.waitAppInitialized;
1605
+
1407
1606
  // Wait starting finish before sleep to avoid conflict
1408
1607
  this.generalStatus === ServiceStatus.STARTING && this.waitStarting && (await this.waitStarting);
1608
+ this.generalStatus === ServiceStatus.STARTING_FULL && this.waitStartingFull && (await this.waitStartingFull);
1409
1609
  this.eventService.emit('general.sleep', true);
1410
1610
 
1411
1611
  // Avoid sleep multiple times
@@ -1434,6 +1634,9 @@ export default class KoniState {
1434
1634
  this.waitSleeping = null;
1435
1635
  }
1436
1636
  async _start() {
1637
+ // Wait for app initialized before start
1638
+ await this.eventService.waitAppInitialized;
1639
+
1437
1640
  // Wait sleep finish before start to avoid conflict
1438
1641
  this.generalStatus === ServiceStatus.STOPPING && this.waitSleeping && (await this.waitSleeping);
1439
1642
 
@@ -1459,15 +1662,37 @@ export default class KoniState {
1459
1662
  }
1460
1663
 
1461
1664
  // Start services
1462
- await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start()]);
1665
+ this.eventService.emit('general.start', true);
1463
1666
 
1464
1667
  // Complete starting
1465
- starting.resolve();
1466
1668
  this.waitStarting = null;
1467
1669
  this.generalStatus = ServiceStatus.STARTED;
1670
+ starting.resolve();
1671
+ }
1672
+ async _startFull() {
1673
+ // Continue wait existed starting process
1674
+ if (this.generalStatus === ServiceStatus.STARTING) {
1675
+ await this.waitStarting;
1676
+ }
1677
+
1678
+ // Always start full from start state
1679
+ if (this.generalStatus !== ServiceStatus.STARTED) {
1680
+ return;
1681
+ }
1682
+ this.generalStatus = ServiceStatus.STARTING_FULL;
1683
+ const startingFull = createPromiseHandler();
1684
+ this.waitStartingFull = startingFull.promise;
1685
+ await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start()]);
1686
+ this.eventService.emit('general.start_full', true);
1687
+ this.waitStartingFull = null;
1688
+ this.generalStatus = ServiceStatus.STARTED_FULL;
1689
+ startingFull.resolve();
1468
1690
  }
1469
- async wakeup() {
1691
+ async wakeup(fullWakeup = false) {
1470
1692
  await this._start();
1693
+ if (fullWakeup) {
1694
+ await this._startFull();
1695
+ }
1471
1696
  }
1472
1697
  cancelSubscription(id) {
1473
1698
  if (isSubscriptionRunning(id)) {
@@ -1,5 +1,5 @@
1
1
  /// <reference types="chrome" />
2
- import { RequestAddPspToken } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { BitcoinRequestGetAddressesResult, RequestAddPspToken } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { MessageTypes, RequestTypes, ResponseTypes } from '@subwallet/extension-base/background/types';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  import { AuthUrlInfo, AuthUrls } from '@subwallet/extension-base/services/request-service/types';
@@ -42,7 +42,6 @@ export default class KoniTabs {
42
42
  private checkAndHandleProviderStatus;
43
43
  private getEvmProvider;
44
44
  private performWeb3Method;
45
- canUseAccount(address: string, url: string): Promise<boolean>;
46
45
  private evmSign;
47
46
  evmSendTransaction(id: string, url: string, { params }: RequestArguments): Promise<string>;
48
47
  private handleEvmRequest;
@@ -60,5 +59,11 @@ export default class KoniTabs {
60
59
  private cardanoSignData;
61
60
  private cardanoSignTransaction;
62
61
  private cardanoSubmitTransaction;
62
+ isBitcoinPublicRequest(type: string, request: RequestArguments): boolean;
63
+ bitcoinGetAddresses(url: string): Promise<BitcoinRequestGetAddressesResult>;
64
+ private bitcoinSign;
65
+ private bitcoinSignPspt;
66
+ private bitcoinSendTransfer;
67
+ private handleBitcoinRequest;
63
68
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], url: string, port: chrome.runtime.Port): Promise<ResponseTypes[keyof ResponseTypes]>;
64
69
  }
@@ -3,11 +3,12 @@
3
3
 
4
4
  import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs';
5
5
  import { _AssetType } from '@subwallet/chain-list/types';
6
+ import { BitcoinProviderError } from '@subwallet/extension-base/background/errors/BitcoinProviderError';
6
7
  import { CardanoProviderError } from '@subwallet/extension-base/background/errors/CardanoProviderError';
7
8
  import { EvmProviderError } from '@subwallet/extension-base/background/errors/EvmProviderError';
8
9
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
9
10
  import { createSubscription, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
10
- import { CardanoProviderErrorType, EvmProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
11
+ import { BitcoinProviderErrorType, CardanoProviderErrorType, EvmProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
11
12
  import RequestBytesSign from '@subwallet/extension-base/background/RequestBytesSign';
12
13
  import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
13
14
  import { ALL_ACCOUNT_KEY, CRON_GET_API_MAP_STATUS, MAX_COLLATERAL_AMOUNT, PERMISSIONS_TO_REVOKE } from '@subwallet/extension-base/constants';
@@ -18,11 +19,12 @@ import { _generateCustomProviderKey } from '@subwallet/extension-base/services/c
18
19
  import { hasSufficientCardanoValue } from '@subwallet/extension-base/services/request-service/helper';
19
20
  import { DEFAULT_CHAIN_PATROL_ENABLE } from '@subwallet/extension-base/services/setting-service/constants';
20
21
  import { convertCardanoAddressToHex, getEVMChainInfo, reformatAddress, stripUrl } from '@subwallet/extension-base/utils';
21
- import { CardanoKeypairTypes, EthereumKeypairTypes, SubstrateKeypairTypes, TonKeypairTypes } from '@subwallet/keyring/types';
22
+ import { BitcoinKeypairTypes, CardanoKeypairTypes, EthereumKeypairTypes, SubstrateKeypairTypes, TonKeypairTypes } from '@subwallet/keyring/types';
23
+ import { getBitcoinAddressInfo } from '@subwallet/keyring/utils';
22
24
  import { keyring } from '@subwallet/ui-keyring';
23
25
  import Web3 from 'web3';
24
26
  import { checkIfDenied } from '@polkadot/phishing';
25
- import { isArray, isNumber } from '@polkadot/util';
27
+ import { hexStripPrefix, isArray, isNumber, u8aToHex } from '@polkadot/util';
26
28
  import { isEthereumAddress } from '@polkadot/util-crypto';
27
29
  function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes) {
28
30
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
@@ -38,7 +40,8 @@ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTyp
38
40
  evm: EthereumKeypairTypes,
39
41
  substrate: SubstrateKeypairTypes,
40
42
  ton: TonKeypairTypes,
41
- cardano: CardanoKeypairTypes
43
+ cardano: CardanoKeypairTypes,
44
+ bitcoin: BitcoinKeypairTypes
42
45
  };
43
46
  const isValidTypes = accountAuthTypes.some(authType => {
44
47
  var _validTypes$authType;
@@ -911,10 +914,6 @@ export default class KoniTabs {
911
914
  });
912
915
  });
913
916
  }
914
- async canUseAccount(address, url) {
915
- const allowedAccounts = await this.getCurrentAccount(url, 'evm');
916
- return !!allowedAccounts.find(acc => acc.toLowerCase() === address.toLowerCase());
917
- }
918
917
  async evmSign(id, url, {
919
918
  method,
920
919
  params
@@ -1276,6 +1275,113 @@ export default class KoniTabs {
1276
1275
  throw new CardanoProviderError(CardanoProviderErrorType.INTERNAL_ERROR, 'Failed to submit transaction');
1277
1276
  }
1278
1277
  }
1278
+
1279
+ /// Bitcoin
1280
+
1281
+ isBitcoinPublicRequest(type, request) {
1282
+ return type === 'bitcoin(request)' && ['getAddresses'].includes(request === null || request === void 0 ? void 0 : request.method);
1283
+ }
1284
+ async bitcoinGetAddresses(url) {
1285
+ try {
1286
+ const isCompleted = await this.#koniState.authorizeUrlV2(url, {
1287
+ origin: url,
1288
+ accountAuthTypes: ['bitcoin']
1289
+ });
1290
+ const result = [];
1291
+ if (!isCompleted) {
1292
+ return result;
1293
+ }
1294
+ const authInfo = await this.getAuthInfo(url);
1295
+ if (!authInfo || !authInfo.isAllowedMap || !authInfo.isAllowed) {
1296
+ return result;
1297
+ }
1298
+ const addressesAllowed = await this.getCurrentAccount(url, 'bitcoin');
1299
+ const addressResults = [];
1300
+ addressesAllowed.forEach(address => {
1301
+ const pair = keyring.getPair(address);
1302
+ if (pair.meta.noPublicKey) {
1303
+ return;
1304
+ }
1305
+ const addressInfo = getBitcoinAddressInfo(address);
1306
+ const item = {
1307
+ address,
1308
+ type: addressInfo.type,
1309
+ isTestnet: addressInfo.network === 'testnet'
1310
+ };
1311
+ item.derivationPath = pair.meta.derivationPath;
1312
+ item.publicKey = hexStripPrefix(u8aToHex(pair.publicKey));
1313
+ if (pair.publicKey.length !== 32) {
1314
+ item.tweakedPublicKey = hexStripPrefix(u8aToHex(pair.publicKey.slice(1, 33)));
1315
+ }
1316
+ addressResults.push(item);
1317
+ });
1318
+ return addressResults;
1319
+ } catch (e) {
1320
+ throw new BitcoinProviderError(BitcoinProviderErrorType.USER_REJECTED_REQUEST);
1321
+ }
1322
+ }
1323
+ async bitcoinSign(id, url, {
1324
+ method,
1325
+ params
1326
+ }) {
1327
+ const signResult = await this.#koniState.bitcoinSign(id, url, method, params);
1328
+ if (signResult) {
1329
+ return signResult;
1330
+ } else {
1331
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, 'Failed to sign message');
1332
+ }
1333
+ }
1334
+ async bitcoinSignPspt(id, url, {
1335
+ method,
1336
+ params
1337
+ }) {
1338
+ const psbtParams = params;
1339
+ const signResult = await this.#koniState.bitcoinSignPspt(id, url, psbtParams);
1340
+ if (signResult) {
1341
+ return signResult;
1342
+ } else {
1343
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, 'Failed to sign message');
1344
+ }
1345
+ }
1346
+ async bitcoinSendTransfer(id, url, {
1347
+ params
1348
+ }) {
1349
+ const transactionParams = params;
1350
+ const transactionHash = await this.#koniState.bitcoinSendTransaction(id, url, transactionParams);
1351
+ if (!transactionHash) {
1352
+ throw new BitcoinProviderError(BitcoinProviderErrorType.USER_REJECTED_REQUEST);
1353
+ }
1354
+ return {
1355
+ txid: transactionHash
1356
+ };
1357
+ }
1358
+ async handleBitcoinRequest(id, url, request, port) {
1359
+ const {
1360
+ method
1361
+ } = request;
1362
+ try {
1363
+ switch (method) {
1364
+ case 'getAddresses':
1365
+ return await this.bitcoinGetAddresses(url);
1366
+ case 'signMessage':
1367
+ return await this.bitcoinSign(id, url, request);
1368
+ case 'signPsbt':
1369
+ return await this.bitcoinSignPspt(id, url, request);
1370
+ case 'sendTransfer':
1371
+ return await this.bitcoinSendTransfer(id, url, request);
1372
+ default:
1373
+ throw new Error(`Method ${method} is not supported by SubWalletBitcoin provider`);
1374
+ }
1375
+ } catch (e) {
1376
+ // @ts-ignore
1377
+ if (e.code) {
1378
+ throw e;
1379
+ } else {
1380
+ console.error(e);
1381
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR, e === null || e === void 0 ? void 0 : e.toString());
1382
+ }
1383
+ }
1384
+ }
1279
1385
  async handle(id, type, request, url, port) {
1280
1386
  if (type === 'pub(phishing.redirectIfDenied)') {
1281
1387
  return this.redirectIfPhishing(url);
@@ -1286,7 +1392,7 @@ export default class KoniTabs {
1286
1392
 
1287
1393
  // Wait for account ready and chain ready
1288
1394
  await Promise.all([this.#koniState.eventService.waitAccountReady, this.#koniState.eventService.waitChainReady]);
1289
- if (!['pub(authorize.tabV2)', 'pub(accounts.subscribeV2)'].includes(type) && !this.isEvmPublicRequest(type, request)) {
1395
+ if (!['pub(authorize.tabV2)', 'pub(accounts.subscribeV2)'].includes(type) && !this.isEvmPublicRequest(type, request) && !this.isBitcoinPublicRequest(type, request)) {
1290
1396
  await this.#koniState.ensureUrlAuthorizedV2(url).catch(e => {
1291
1397
  if (type.startsWith('evm')) {
1292
1398
  throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, e.message);
@@ -1357,6 +1463,10 @@ export default class KoniTabs {
1357
1463
  return await this.cardanoSignTransaction(id, url, request);
1358
1464
  case 'cardano(transaction.submit)':
1359
1465
  return await this.cardanoSubmitTransaction(id, url, request);
1466
+
1467
+ // Bitcoin
1468
+ case 'bitcoin(request)':
1469
+ return await this.handleBitcoinRequest(id, url, request, port);
1360
1470
  default:
1361
1471
  throw new Error(`Unable to handle message of type ${type}`);
1362
1472
  }