@subwallet/extension-base 1.3.20-0 → 1.3.22-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 (123) hide show
  1. package/background/KoniTypes.d.ts +8 -1
  2. package/cjs/defaults.js +1 -1
  3. package/cjs/koni/background/handlers/Extension.js +519 -90
  4. package/cjs/packageInfo.js +1 -1
  5. package/cjs/services/chain-service/constants.js +8 -3
  6. package/cjs/services/chain-service/handler/EvmApi.js +1 -3
  7. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +3 -2
  8. package/cjs/services/chain-service/index.js +9 -0
  9. package/cjs/services/chain-service/utils/patch.js +1 -1
  10. package/cjs/services/earning-service/constants/chains.js +2 -1
  11. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +19 -8
  12. package/cjs/services/earning-service/handlers/native-staking/mythos.js +337 -0
  13. package/cjs/services/earning-service/handlers/special.js +16 -10
  14. package/cjs/services/earning-service/service.js +4 -0
  15. package/cjs/services/earning-service/utils/index.js +2 -0
  16. package/cjs/services/history-service/helpers/recoverHistoryStatus.js +14 -5
  17. package/cjs/services/history-service/index.js +15 -3
  18. package/cjs/services/inapp-notification-service/index.js +78 -0
  19. package/cjs/services/inapp-notification-service/interfaces.js +2 -0
  20. package/cjs/services/keyring-service/context/state.js +2 -1
  21. package/cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
  22. package/cjs/services/migration-service/scripts/databases/ClearMetadataForChains.js +40 -0
  23. package/cjs/services/migration-service/scripts/databases/ClearMetadataForMythos.js +15 -0
  24. package/cjs/services/migration-service/scripts/index.js +6 -2
  25. package/cjs/services/request-service/handler/EvmRequestHandler.js +10 -0
  26. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +4 -3
  27. package/cjs/services/request-service/index.js +2 -2
  28. package/cjs/services/setting-service/constants.js +5 -2
  29. package/cjs/services/storage-service/DatabaseService.js +101 -2
  30. package/cjs/services/storage-service/databases/index.js +3 -0
  31. package/cjs/services/storage-service/db-stores/Metadata.js +3 -0
  32. package/cjs/services/storage-service/db-stores/Migration.js +6 -1
  33. package/cjs/services/storage-service/db-stores/ProcessTransaction.js +47 -0
  34. package/cjs/services/storage-service/db-stores/Transaction.js +2 -0
  35. package/cjs/services/storage-service/db-stores/index.js +8 -1
  36. package/cjs/services/swap-service/handler/asset-hub/handler.js +30 -11
  37. package/cjs/services/swap-service/handler/hydradx-handler.js +18 -10
  38. package/cjs/services/swap-service/index.js +3 -0
  39. package/cjs/services/swap-service/utils.js +1 -0
  40. package/cjs/services/transaction-service/index.js +218 -9
  41. package/cjs/types/index.js +11 -0
  42. package/cjs/types/setting.js +1 -0
  43. package/cjs/types/swap/index.js +4 -1
  44. package/cjs/types/transaction/index.js +11 -0
  45. package/cjs/types/transaction/process.js +28 -0
  46. package/cjs/types/yield/actions/join/submit.js +16 -1
  47. package/defaults.d.ts +1 -1
  48. package/defaults.js +1 -1
  49. package/koni/background/handlers/Extension.d.ts +5 -0
  50. package/koni/background/handlers/Extension.js +437 -12
  51. package/package.json +52 -22
  52. package/packageInfo.js +1 -1
  53. package/services/chain-service/constants.js +8 -3
  54. package/services/chain-service/handler/EvmApi.js +1 -3
  55. package/services/chain-service/handler/SubstrateChainHandler.js +3 -2
  56. package/services/chain-service/index.d.ts +1 -0
  57. package/services/chain-service/index.js +9 -0
  58. package/services/chain-service/utils/patch.js +1 -1
  59. package/services/earning-service/constants/chains.d.ts +1 -0
  60. package/services/earning-service/constants/chains.js +2 -1
  61. package/services/earning-service/handlers/liquid-staking/stella-swap.js +19 -8
  62. package/services/earning-service/handlers/native-staking/mythos.d.ts +35 -0
  63. package/services/earning-service/handlers/native-staking/mythos.js +329 -0
  64. package/services/earning-service/handlers/special.js +18 -12
  65. package/services/earning-service/service.js +4 -0
  66. package/services/earning-service/utils/index.js +2 -0
  67. package/services/history-service/helpers/recoverHistoryStatus.js +14 -5
  68. package/services/history-service/index.d.ts +6 -5
  69. package/services/history-service/index.js +16 -5
  70. package/services/inapp-notification-service/index.d.ts +2 -0
  71. package/services/inapp-notification-service/index.js +79 -1
  72. package/services/inapp-notification-service/interfaces.d.ts +8 -1
  73. package/services/inapp-notification-service/interfaces.js +2 -0
  74. package/services/keyring-service/context/state.d.ts +1 -1
  75. package/services/keyring-service/context/state.js +3 -2
  76. package/services/migration-service/scripts/databases/ClearMetadataDatabase.d.ts +3 -3
  77. package/services/migration-service/scripts/databases/ClearMetadataDatabase.js +3 -23
  78. package/services/migration-service/scripts/databases/ClearMetadataForChains.d.ts +5 -0
  79. package/services/migration-service/scripts/databases/ClearMetadataForChains.js +32 -0
  80. package/services/migration-service/scripts/databases/ClearMetadataForMythos.d.ts +4 -0
  81. package/services/migration-service/scripts/databases/ClearMetadataForMythos.js +7 -0
  82. package/services/migration-service/scripts/index.d.ts +1 -0
  83. package/services/migration-service/scripts/index.js +4 -1
  84. package/services/request-service/handler/EvmRequestHandler.js +10 -0
  85. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -1
  86. package/services/request-service/handler/SubstrateRequestHandler.js +4 -3
  87. package/services/request-service/index.d.ts +1 -1
  88. package/services/request-service/index.js +2 -2
  89. package/services/setting-service/constants.d.ts +1 -0
  90. package/services/setting-service/constants.js +3 -1
  91. package/services/storage-service/DatabaseService.d.ts +13 -3
  92. package/services/storage-service/DatabaseService.js +103 -4
  93. package/services/storage-service/databases/index.d.ts +2 -1
  94. package/services/storage-service/databases/index.js +3 -0
  95. package/services/storage-service/db-stores/Metadata.d.ts +1 -0
  96. package/services/storage-service/db-stores/Metadata.js +3 -0
  97. package/services/storage-service/db-stores/Migration.d.ts +1 -0
  98. package/services/storage-service/db-stores/Migration.js +6 -1
  99. package/services/storage-service/db-stores/ProcessTransaction.d.ts +14 -0
  100. package/services/storage-service/db-stores/ProcessTransaction.js +39 -0
  101. package/services/storage-service/db-stores/Transaction.js +2 -0
  102. package/services/storage-service/db-stores/index.d.ts +1 -0
  103. package/services/storage-service/db-stores/index.js +2 -1
  104. package/services/swap-service/handler/asset-hub/handler.js +30 -11
  105. package/services/swap-service/handler/hydradx-handler.js +18 -10
  106. package/services/swap-service/index.js +3 -0
  107. package/services/swap-service/utils.js +1 -0
  108. package/services/transaction-service/index.d.ts +19 -1
  109. package/services/transaction-service/index.js +220 -11
  110. package/services/transaction-service/types.d.ts +13 -4
  111. package/types/index.d.ts +1 -0
  112. package/types/index.js +1 -0
  113. package/types/setting.d.ts +3 -0
  114. package/types/setting.js +1 -0
  115. package/types/swap/index.d.ts +3 -2
  116. package/types/swap/index.js +4 -1
  117. package/types/transaction/index.d.ts +1 -0
  118. package/types/transaction/index.js +1 -0
  119. package/types/transaction/process.d.ts +84 -0
  120. package/types/transaction/process.js +20 -0
  121. package/types/transaction/request.d.ts +3 -1
  122. package/types/yield/actions/join/submit.d.ts +18 -3
  123. package/types/yield/actions/join/submit.js +11 -1
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.3.20-0'
16
+ version: '1.3.22-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -115,7 +115,10 @@ const _STAKING_ERA_LENGTH_MAP = {
115
115
  polkadex: 24,
116
116
  avail_mainnet: 24,
117
117
  cere: 24,
118
- analog_timechain: 12
118
+ analog_timechain: 12,
119
+ muse_testnet: 25 * 6 / 60 / 60,
120
+ // 25 blocks per session
121
+ mythos: 24
119
122
  };
120
123
  exports._STAKING_ERA_LENGTH_MAP = _STAKING_ERA_LENGTH_MAP;
121
124
  const _EXPECTED_BLOCK_TIME = {
@@ -149,7 +152,9 @@ const _EXPECTED_BLOCK_TIME = {
149
152
  enjin_relaychain: 6,
150
153
  availTuringTest: 20,
151
154
  avail_mainnet: 20,
152
- dentnet: 3
155
+ dentnet: 3,
156
+ muse_testnet: 6,
157
+ mythos: 6
153
158
  };
154
159
  exports._EXPECTED_BLOCK_TIME = _EXPECTED_BLOCK_TIME;
155
160
  const _PARACHAIN_INFLATION_DISTRIBUTION = {
@@ -266,7 +271,7 @@ const _TRANSFER_CHAIN_GROUP = {
266
271
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
267
272
  // crab: ['crab', 'pangolin'],
268
273
  bitcountry: ['pioneer', 'bitcountry'],
269
- statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain'],
274
+ statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain', 'westend_assethub'],
270
275
  riochain: ['riochain'],
271
276
  sora_substrate: ['sora_substrate'],
272
277
  avail: ['kate', 'goldberg_testnet'],
@@ -126,12 +126,10 @@ class EvmApi {
126
126
  return this.disconnect();
127
127
  }
128
128
  onConnect() {
129
+ this.isReadyHandler.resolve(this);
129
130
  if (!this.isApiConnected) {
130
131
  console.log(`Connected to ${this.chainSlug} at ${this.apiUrl}`);
131
132
  this.isApiReady = true;
132
- if (this.isApiReadyOnce) {
133
- this.isReadyHandler.resolve(this);
134
- }
135
133
  }
136
134
  this.updateConnectionStatus(_types._ChainConnectionStatus.CONNECTED);
137
135
  }
@@ -266,7 +266,7 @@ class SubstrateChainHandler extends _AbstractChainHandler.AbstractChainHandler {
266
266
  substrateAPI === null || substrateAPI === void 0 ? void 0 : substrateAPI.destroy().catch(console.error);
267
267
  }
268
268
  async initApi(chainSlug, apiUrl) {
269
- var _this$parent2;
269
+ var _this$parent2, _this$parent3;
270
270
  let {
271
271
  externalApiPromise,
272
272
  onUpdateStatus,
@@ -289,7 +289,8 @@ class SubstrateChainHandler extends _AbstractChainHandler.AbstractChainHandler {
289
289
  updateMetadata(existed);
290
290
  return existed;
291
291
  }
292
- const metadata = await ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.getMetadata(chainSlug));
292
+ const useMetadata = await ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.isUseMetadataToCreateApi(chainSlug));
293
+ const metadata = useMetadata === false ? undefined : await ((_this$parent3 = this.parent) === null || _this$parent3 === void 0 ? void 0 : _this$parent3.getMetadata(chainSlug));
293
294
  const apiObject = new _SubstrateApi2.SubstrateApi(chainSlug, apiUrl, {
294
295
  providerName,
295
296
  metadata,
@@ -15,6 +15,7 @@ var _TonChainHandler = require("@subwallet/extension-base/services/chain-service
15
15
  var _types2 = require("@subwallet/extension-base/services/chain-service/handler/types");
16
16
  var _types3 = require("@subwallet/extension-base/services/chain-service/types");
17
17
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
18
+ var _scripts = require("@subwallet/extension-base/services/migration-service/scripts");
18
19
  var _AssetSetting = _interopRequireDefault(require("@subwallet/extension-base/stores/AssetSetting"));
19
20
  var _utils2 = require("@subwallet/extension-base/utils");
20
21
  var _rxjs = require("rxjs");
@@ -1857,5 +1858,13 @@ class ChainService {
1857
1858
  return chainAsset.originChain === chainSlug && (chainAsset.assetType === _types._AssetType.NATIVE || (0, _utils._isAssetCanPayTxFee)(chainAsset));
1858
1859
  }).map(chainAsset => chainAsset.slug);
1859
1860
  }
1861
+ async isUseMetadataToCreateApi(chain) {
1862
+ const isMythos = ['mythos', 'muse_testnet'].includes(chain);
1863
+ if (isMythos) {
1864
+ return this.dbService.hasRunScript(_scripts.MYTHOS_MIGRATION_KEY);
1865
+ } else {
1866
+ return true;
1867
+ }
1868
+ }
1860
1869
  }
1861
1870
  exports.ChainService = ChainService;
@@ -11,7 +11,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
11
11
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
12
12
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
13
13
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
14
- const ChainListVersion = '0.2.98'; // update this when build chainlist
14
+ const ChainListVersion = '0.2.99'; // update this when build chainlist
15
15
 
16
16
  // todo: move this interface to chainlist
17
17
 
@@ -23,7 +23,8 @@ const _STAKING_CHAIN_GROUP = {
23
23
  lending: ['interlay'],
24
24
  krest_network: ['krest_network'],
25
25
  manta: ['manta_network'],
26
- bittensor: ['bittensor', 'bittensor_devnet']
26
+ bittensor: ['bittensor', 'bittensor_devnet'],
27
+ mythos: ['mythos', 'muse_testnet']
27
28
  };
28
29
  exports._STAKING_CHAIN_GROUP = _STAKING_CHAIN_GROUP;
29
30
  const TON_CHAINS = ['ton', 'ton_testnet'];
@@ -27,6 +27,7 @@ const getStellaswapLiquidStakingContract = function (networkKey, assetAddress, e
27
27
  exports.getStellaswapLiquidStakingContract = getStellaswapLiquidStakingContract;
28
28
  const APR_STATS_URL = 'https://apr-api.stellaswap.com/api/v1/stdot';
29
29
  const SUBWALLET_REFERRAL = '0x7e6815f45E624768548d085231f2d453f16FD7DD';
30
+ const TOP_HOLDER = '0x4300e09284e3bB4d9044DdAB31EfAF5f3301DABa';
30
31
  class StellaSwapLiquidStakingPoolHandler extends _base.default {
31
32
  inputAsset = 'moonbeam-LOCAL-xcDOT';
32
33
  altInputAsset = '';
@@ -207,9 +208,15 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
207
208
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
208
209
  await allowanceCall.call(), evmApi.api.eth.getGasPrice()]);
209
210
  if (!allowance || parseInt(allowance) <= 0) {
211
+ const metadata = {
212
+ tokenApprove: inputTokenSlug,
213
+ contractAddress: (0, _utils._getContractAddressOfToken)(inputTokenInfo),
214
+ spenderAddress: (0, _utils._getContractAddressOfToken)(derivativeTokenInfo)
215
+ };
210
216
  const step = {
211
217
  name: 'Authorize token approval',
212
- type: _types.YieldStepType.TOKEN_APPROVAL
218
+ type: _types.YieldStepType.TOKEN_APPROVAL,
219
+ metadata: metadata
213
220
  };
214
221
 
215
222
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
@@ -232,13 +239,17 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
232
239
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
233
240
  const depositCall = stakingContract.methods.deposit(params.amount);
234
241
  let estimatedDepositGas = 0;
235
- try {
236
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
237
- estimatedDepositGas = await depositCall.estimateGas({
238
- from: params.address
239
- });
240
- } catch (e) {
241
- console.error(e);
242
+ const addressToTests = [params.address, TOP_HOLDER];
243
+ for (const address of addressToTests) {
244
+ try {
245
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
246
+ estimatedDepositGas = await depositCall.estimateGas({
247
+ from: address
248
+ });
249
+ break;
250
+ } catch (e) {
251
+ console.error(e);
252
+ }
242
253
  }
243
254
  const gasPrice = await evmApi.api.eth.getGasPrice();
244
255
  return {
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
+ var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
+ var _utils = require("@subwallet/extension-base/koni/api/staking/bonding/utils");
11
+ var _constants = require("@subwallet/extension-base/services/chain-service/constants");
12
+ var _basePara = _interopRequireDefault(require("@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para"));
13
+ var _types = require("@subwallet/extension-base/types");
14
+ var _utils2 = require("@subwallet/extension-base/utils");
15
+ // Copyright 2019-2022 @subwallet/extension-base
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ class MythosNativeStakingPoolHandler extends _basePara.default {
19
+ availableMethod = {
20
+ join: true,
21
+ defaultUnstake: true,
22
+ fastUnstake: false,
23
+ cancelUnstake: false,
24
+ withdraw: true,
25
+ claimReward: true
26
+ };
27
+
28
+ /* Subscribe pool info */
29
+
30
+ async subscribePoolInfo(callback) {
31
+ let cancel = false;
32
+ const substrateApi = this.substrateApi;
33
+ const nativeToken = this.nativeToken;
34
+ const defaultCallback = async () => {
35
+ const data = {
36
+ ...this.baseInfo,
37
+ type: this.type,
38
+ metadata: {
39
+ ...this.metadataInfo,
40
+ description: this.getDescription()
41
+ }
42
+ };
43
+ const poolInfo = await this.getPoolInfo();
44
+ !poolInfo && callback(data);
45
+ };
46
+ if (!this.isActive) {
47
+ await defaultCallback();
48
+ return () => {
49
+ cancel = true;
50
+ };
51
+ }
52
+ await defaultCallback();
53
+ await substrateApi.isReady;
54
+ const unsub = await substrateApi.api.query.collatorStaking.currentSession(async _session => {
55
+ if (cancel) {
56
+ unsub();
57
+ return;
58
+ }
59
+ const currentSession = _session.toString();
60
+ const maxStakers = substrateApi.api.consts.collatorStaking.maxStakers.toString();
61
+ const unstakeDelay = substrateApi.api.consts.collatorStaking.stakeUnlockDelay.toString();
62
+ const maxStakedCandidates = substrateApi.api.consts.collatorStaking.maxStakedCandidates.toString();
63
+ const sessionTime = _constants._STAKING_ERA_LENGTH_MAP[this.chain] || _constants._STAKING_ERA_LENGTH_MAP.default; // in hours
64
+ const blockTime = _constants._EXPECTED_BLOCK_TIME[this.chain];
65
+ const unstakingPeriod = parseInt(unstakeDelay) * blockTime / 60 / 60;
66
+ const _minStake = await substrateApi.api.query.collatorStaking.minStake();
67
+ const minStake = _minStake.toString();
68
+ const minStakeToHuman = (0, _utils2.formatNumber)(minStake, nativeToken.decimals || 0, _utils2.balanceFormatter);
69
+ const data = {
70
+ ...this.baseInfo,
71
+ type: this.type,
72
+ metadata: {
73
+ ...this.metadataInfo,
74
+ description: this.getDescription(minStakeToHuman)
75
+ },
76
+ statistic: {
77
+ assetEarning: [{
78
+ slug: this.nativeToken.slug
79
+ }],
80
+ maxCandidatePerFarmer: parseInt(maxStakedCandidates),
81
+ maxWithdrawalRequestPerFarmer: 3,
82
+ earningThreshold: {
83
+ join: minStake,
84
+ defaultUnstake: '0',
85
+ fastUnstake: '0'
86
+ },
87
+ era: parseInt(currentSession),
88
+ eraTime: sessionTime,
89
+ unstakingPeriod: unstakingPeriod,
90
+ totalApy: undefined
91
+ // tvl: totalStake.toString(),
92
+ // inflation
93
+ },
94
+
95
+ maxPoolMembers: parseInt(maxStakers)
96
+ };
97
+ callback(data);
98
+ });
99
+ return () => {
100
+ cancel = true;
101
+ unsub();
102
+ };
103
+ }
104
+
105
+ /* Subscribe pool info */
106
+
107
+ /* Subscribe pool position */
108
+
109
+ async subscribePoolPosition(useAddresses, resultCallback) {
110
+ let cancel = false;
111
+ const substrateApi = await this.substrateApi.isReady;
112
+ const defaultInfo = this.baseInfo;
113
+ const unsub = await substrateApi.api.query.collatorStaking.userStake.multi(useAddresses, async userStakes => {
114
+ if (cancel) {
115
+ unsub();
116
+ return;
117
+ }
118
+ if (userStakes) {
119
+ await Promise.all(userStakes.map(async (_userStake, i) => {
120
+ const userStake = _userStake.toPrimitive();
121
+ const owner = (0, _utils2.reformatAddress)(useAddresses[i], 42);
122
+ if (userStake) {
123
+ const nominatorMetadata = await this.parseCollatorMetadata(this.chainInfo, useAddresses[i], substrateApi, userStake);
124
+ resultCallback({
125
+ ...defaultInfo,
126
+ ...nominatorMetadata,
127
+ address: owner,
128
+ type: this.type
129
+ });
130
+ } else {
131
+ resultCallback({
132
+ ...defaultInfo,
133
+ type: this.type,
134
+ address: owner,
135
+ balanceToken: this.nativeToken.slug,
136
+ totalStake: '0',
137
+ activeStake: '0',
138
+ unstakeBalance: '0',
139
+ status: _types.EarningStatus.NOT_STAKING,
140
+ isBondedBefore: false,
141
+ nominations: [],
142
+ unstakings: []
143
+ });
144
+ }
145
+ }));
146
+ }
147
+ });
148
+ return () => {
149
+ cancel = true;
150
+ unsub();
151
+ };
152
+ }
153
+ async parseCollatorMetadata(chainInfo, stakerAddress, substrateApi, userStake) {
154
+ const nominationList = [];
155
+ const unstakingList = [];
156
+ let unstakingBalance = BigInt(0);
157
+ const {
158
+ candidates,
159
+ stake
160
+ } = userStake;
161
+ const [_minStake, _unstaking, _currentBlock, _currentTimestamp] = await Promise.all([substrateApi.api.query.collatorStaking.minStake(), substrateApi.api.query.collatorStaking.releaseQueues(stakerAddress), substrateApi.api.query.system.number(), substrateApi.api.query.timestamp.now()]);
162
+ const minStake = _minStake.toPrimitive();
163
+ const stakingStatus = candidates && !!candidates.length ? _types.EarningStatus.EARNING_REWARD : _types.EarningStatus.NOT_EARNING;
164
+ const isBondedBefore = candidates && !!candidates.length;
165
+ const unstakings = _unstaking.toPrimitive();
166
+ const currentBlock = _currentBlock.toPrimitive();
167
+ const currentTimestamp = _currentTimestamp.toPrimitive();
168
+ const blockDuration = _constants._EXPECTED_BLOCK_TIME[chainInfo.slug];
169
+ if (candidates.length) {
170
+ await Promise.all(candidates.map(async collatorAddress => {
171
+ const _stakeInfo = await substrateApi.api.query.collatorStaking.candidateStake(collatorAddress, stakerAddress);
172
+ const stakeInfo = _stakeInfo.toPrimitive();
173
+ const activeStake = stakeInfo.stake.toString();
174
+ const earningStatus = BigInt(activeStake) > BigInt(0) && BigInt(activeStake) >= BigInt(minStake) ? _types.EarningStatus.EARNING_REWARD : _types.EarningStatus.NOT_EARNING;
175
+ nominationList.push({
176
+ status: earningStatus,
177
+ chain: chainInfo.slug,
178
+ validatorAddress: collatorAddress,
179
+ activeStake,
180
+ validatorMinStake: minStake,
181
+ hasUnstaking: !!unstakings.length
182
+ });
183
+ }));
184
+ }
185
+ if (unstakings.length) {
186
+ unstakings.forEach(unstaking => {
187
+ const releaseBlock = unstaking.block;
188
+ const unstakeAmount = unstaking.amount;
189
+ const isClaimable = currentBlock >= releaseBlock;
190
+ const targetTimestampMs = (releaseBlock - currentBlock) * blockDuration * 1000 + currentTimestamp;
191
+ unstakingBalance = unstakingBalance + BigInt(unstakeAmount);
192
+ unstakingList.push({
193
+ chain: chainInfo.slug,
194
+ status: isClaimable ? _types.UnstakingStatus.CLAIMABLE : _types.UnstakingStatus.UNLOCKING,
195
+ claimable: unstakeAmount,
196
+ targetTimestampMs
197
+ });
198
+ });
199
+ }
200
+ return {
201
+ status: stakingStatus,
202
+ balanceToken: this.nativeToken.slug,
203
+ totalStake: (BigInt(stake) + unstakingBalance).toString(),
204
+ activeStake: stake,
205
+ unstakeBalance: unstakingBalance.toString() || '0',
206
+ isBondedBefore: isBondedBefore,
207
+ nominations: nominationList,
208
+ unstakings: unstakingList
209
+ };
210
+ }
211
+
212
+ /* Subscribe pool position */
213
+
214
+ /* Get pool targets */
215
+
216
+ async getPoolTargets() {
217
+ const substrateApi = await this.substrateApi.isReady;
218
+ const [_allCollators, _minStake, _commission] = await Promise.all([substrateApi.api.query.collatorStaking.candidates.entries(), substrateApi.api.query.collatorStaking.minStake(), substrateApi.api.query.collatorStaking.collatorRewardPercentage()]);
219
+ const maxStakersPerCollator = substrateApi.api.consts.collatorStaking.maxStakers.toPrimitive();
220
+ return _allCollators.map(_collator => {
221
+ const _collatorAddress = _collator[0].toHuman();
222
+ const collatorAddress = _collatorAddress[0];
223
+ const collatorInfo = _collator[1].toPrimitive();
224
+ const bnTotalStake = BigInt(collatorInfo.stake);
225
+ const numOfStakers = parseInt(collatorInfo.stakers);
226
+ const isCrowded = numOfStakers >= maxStakersPerCollator;
227
+ return {
228
+ address: collatorAddress,
229
+ chain: this.chain,
230
+ totalStake: bnTotalStake.toString(),
231
+ ownStake: '0',
232
+ otherStake: bnTotalStake.toString(),
233
+ minBond: _minStake.toPrimitive(),
234
+ nominatorCount: numOfStakers,
235
+ commission: (0, _utils.getCommission)(_commission.toString()),
236
+ blocked: false,
237
+ isVerified: false,
238
+ isCrowded
239
+ };
240
+ });
241
+ }
242
+
243
+ /* Get pool targets */
244
+
245
+ /* Join pool action */
246
+
247
+ async createJoinExtrinsic(data, positionInfo) {
248
+ var _substrateApi$api$cal, _substrateApi$api$cal2;
249
+ const substrateApi = await this.substrateApi.isReady;
250
+ const {
251
+ address,
252
+ amount,
253
+ selectedValidators
254
+ } = data;
255
+ const selectedValidatorInfo = selectedValidators[0];
256
+ const _hasReward = await ((_substrateApi$api$cal = substrateApi.api.call) === null || _substrateApi$api$cal === void 0 ? void 0 : (_substrateApi$api$cal2 = _substrateApi$api$cal.collatorStakingApi) === null || _substrateApi$api$cal2 === void 0 ? void 0 : _substrateApi$api$cal2.shouldClaim(address));
257
+ const hasReward = _hasReward === null || _hasReward === void 0 ? void 0 : _hasReward.toPrimitive();
258
+ const extrinsicList = [];
259
+ if (positionInfo !== null && positionInfo !== void 0 && positionInfo.isBondedBefore && hasReward) {
260
+ extrinsicList.push(substrateApi.api.tx.collatorStaking.claimRewards());
261
+ }
262
+ extrinsicList.push(...[substrateApi.api.tx.collatorStaking.lock(amount), substrateApi.api.tx.collatorStaking.stake([{
263
+ candidate: selectedValidatorInfo.address,
264
+ stake: amount
265
+ }])]);
266
+ return [substrateApi.api.tx.utility.batchAll(extrinsicList), {
267
+ slug: this.nativeToken.slug,
268
+ amount: '0'
269
+ }];
270
+ }
271
+
272
+ /* Join pool action */
273
+
274
+ /* Leave pool action */
275
+
276
+ async handleYieldUnstake(amount, address, selectedTarget) {
277
+ var _substrateApi$api$cal3, _substrateApi$api$cal4;
278
+ const substrateApi = await this.substrateApi.isReady;
279
+ const _hasReward = await ((_substrateApi$api$cal3 = substrateApi.api.call) === null || _substrateApi$api$cal3 === void 0 ? void 0 : (_substrateApi$api$cal4 = _substrateApi$api$cal3.collatorStakingApi) === null || _substrateApi$api$cal4 === void 0 ? void 0 : _substrateApi$api$cal4.shouldClaim(address));
280
+ const hasReward = _hasReward === null || _hasReward === void 0 ? void 0 : _hasReward.toPrimitive();
281
+ const extrinsicList = [];
282
+ if (hasReward) {
283
+ extrinsicList.push(substrateApi.api.tx.collatorStaking.claimRewards());
284
+ }
285
+ extrinsicList.push(...[substrateApi.api.tx.collatorStaking.unstakeFrom(selectedTarget), substrateApi.api.tx.collatorStaking.unlock(null) // ignore amount to unlock all
286
+ ]);
287
+
288
+ return [_KoniTypes.ExtrinsicType.STAKING_UNBOND, substrateApi.api.tx.utility.batchAll(extrinsicList)];
289
+ }
290
+
291
+ /* Leave pool action */
292
+
293
+ /* Get pool reward */
294
+ async getPoolReward(useAddresses, callback) {
295
+ let cancel = false;
296
+ const substrateApi = this.substrateApi;
297
+ await substrateApi.isReady;
298
+ if (substrateApi.api.call.collatorStakingApi) {
299
+ await Promise.all(useAddresses.map(async address => {
300
+ if (!cancel) {
301
+ const _unclaimedReward = await substrateApi.api.call.collatorStakingApi.totalRewards(address);
302
+ const earningRewardItem = {
303
+ ...this.baseInfo,
304
+ address: address,
305
+ type: this.type,
306
+ unclaimedReward: (_unclaimedReward === null || _unclaimedReward === void 0 ? void 0 : _unclaimedReward.toString()) || '0',
307
+ state: _KoniTypes.APIItemState.READY
308
+ };
309
+ if (_unclaimedReward.toString() !== '0') {
310
+ await this.createClaimNotification(earningRewardItem, this.nativeToken);
311
+ }
312
+ callback(earningRewardItem);
313
+ }
314
+ }));
315
+ }
316
+ return () => {
317
+ cancel = false;
318
+ };
319
+ }
320
+ /* Get pool reward */
321
+
322
+ /* Other action */
323
+
324
+ async handleYieldCancelUnstake() {
325
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
326
+ }
327
+ async handleYieldWithdraw(address, unstakingInfo) {
328
+ const substrateApi = await this.substrateApi.isReady;
329
+ return substrateApi.api.tx.collatorStaking.release();
330
+ }
331
+ async handleYieldClaimReward(address, bondReward) {
332
+ const substrateApi = await this.substrateApi.isReady;
333
+ return substrateApi.api.tx.collatorStaking.claimRewards();
334
+ }
335
+ /* Other action */
336
+ }
337
+ exports.default = MythosNativeStakingPoolHandler;
@@ -223,15 +223,6 @@ class BaseSpecialStakingPoolHandler extends _base.default {
223
223
  const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
224
224
  const symbol = altInputTokenInfo.symbol;
225
225
  const networkName = altChainInfo.name;
226
- const step = {
227
- metadata: {
228
- sendingValue: bnAmount.toString(),
229
- originTokenInfo: altInputTokenInfo,
230
- destinationTokenInfo: inputTokenInfo
231
- },
232
- name: `Transfer ${symbol} from ${networkName}`,
233
- type: _types.YieldStepType.XCM
234
- };
235
226
  const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
236
227
  const id = (0, _getId.getId)();
237
228
  const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
@@ -252,9 +243,24 @@ class BaseSpecialStakingPoolHandler extends _base.default {
252
243
 
253
244
  const fee = {
254
245
  slug: altInputTokenSlug,
255
- amount: Math.round(xcmFeeInfo.partialFee * 1.2).toString() // TODO
246
+ amount: Math.round(xcmFeeInfo.partialFee * _constants.XCM_MIN_AMOUNT_RATIO).toString() // TODO
256
247
  };
257
248
 
249
+ let bnTransferAmount = bnAmount.sub(bnInputTokenBalance);
250
+ if ((0, _utils2._isNativeToken)(altInputTokenInfo)) {
251
+ const bnXcmFee = new _util.BN(fee.amount || 0); // xcm fee is paid in native token but swap token is not always native token
252
+
253
+ bnTransferAmount = bnTransferAmount.add(bnXcmFee);
254
+ }
255
+ const step = {
256
+ metadata: {
257
+ sendingValue: bnTransferAmount.toString(),
258
+ originTokenInfo: altInputTokenInfo,
259
+ destinationTokenInfo: inputTokenInfo
260
+ },
261
+ name: `Transfer ${symbol} from ${networkName}`,
262
+ type: _types.YieldStepType.XCM
263
+ };
258
264
  return [step, fee];
259
265
  }
260
266
  }
@@ -12,6 +12,7 @@ var _types = require("@subwallet/extension-base/services/base/types");
12
12
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
13
13
  var _constants2 = require("@subwallet/extension-base/services/earning-service/constants");
14
14
  var _base = _interopRequireDefault(require("@subwallet/extension-base/services/earning-service/handlers/liquid-staking/base"));
15
+ var _mythos = _interopRequireDefault(require("@subwallet/extension-base/services/earning-service/handlers/native-staking/mythos"));
15
16
  var _types2 = require("@subwallet/extension-base/types");
16
17
  var _utils2 = require("@subwallet/extension-base/utils");
17
18
  var _fetchStaticCache = require("@subwallet/extension-base/utils/fetchStaticCache");
@@ -75,6 +76,9 @@ class EarningService {
75
76
  if (_constants2._STAKING_CHAIN_GROUP.bittensor.includes(chain)) {
76
77
  handlers.push(new _handlers.TaoNativeStakingPoolHandler(this.state, chain));
77
78
  }
79
+ if (_constants2._STAKING_CHAIN_GROUP.mythos.includes(chain)) {
80
+ handlers.push(new _mythos.default(this.state, chain));
81
+ }
78
82
  if (_constants2._STAKING_CHAIN_GROUP.nominationPool.includes(chain)) {
79
83
  handlers.push(new _handlers.NominationPoolHandler(this.state, chain));
80
84
  }
@@ -118,6 +118,8 @@ function isActionFromValidator(stakingType, chain) {
118
118
  return true;
119
119
  } else if (_constants._STAKING_CHAIN_GROUP.bittensor.includes(chain)) {
120
120
  return true;
121
+ } else if (_constants._STAKING_CHAIN_GROUP.mythos.includes(chain)) {
122
+ return true;
121
123
  }
122
124
  return false;
123
125
  }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.historyRecover = exports.HistoryRecoverStatus = void 0;
7
7
  var _utils = require("@subwallet/extension-base/utils");
8
+ var _util = require("@polkadot/util");
8
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
9
10
  // SPDX-License-Identifier: Apache-2.0
10
11
  let HistoryRecoverStatus;
@@ -37,7 +38,7 @@ const substrateRecover = async (history, chainService) => {
37
38
  const _api = await substrateApi.isReady;
38
39
  const api = _api.api;
39
40
  if (!blockHash) {
40
- if (!nonce || !startBlock) {
41
+ if (nonce === undefined || startBlock === undefined) {
41
42
  console.log(`Fail to find extrinsic for ${address} on ${chain}: With nonce ${nonce || 'undefined'} from block ${startBlock || 'undefined'}`);
42
43
  return {
43
44
  status: HistoryRecoverStatus.LACK_INFO
@@ -47,7 +48,7 @@ const substrateRecover = async (history, chainService) => {
47
48
  for (let i = 1, found = false; i < BLOCK_LIMIT && !found && startBlock + i <= currentBlock; i++) {
48
49
  const blockHash = (await api.rpc.chain.getBlockHash(startBlock + i)).toHex();
49
50
  const block = await api.rpc.chain.getBlock(blockHash);
50
- const extrinsics = block.block.extrinsics;
51
+ const extrinsics = block.block.extrinsics.toArray();
51
52
  let index;
52
53
  for (const [idx, extrinsic] of Object.entries(extrinsics)) {
53
54
  if (extrinsic.signer && (0, _utils.isSameAddress)(from, extrinsic.signer.toString()) && nonce === extrinsic.nonce.toNumber()) {
@@ -154,16 +155,24 @@ const evmRecover = async (history, chainService) => {
154
155
  try {
155
156
  const evmApi = chainService.getEvmApi(chain);
156
157
  if (evmApi) {
157
- const _api = await evmApi.isReady;
158
+ const _api = await Promise.race([evmApi.isReady, new Promise((resolve, reject) => {
159
+ const createTimeout = callback => {
160
+ setTimeout(callback, 10000);
161
+ };
162
+ createTimeout(() => {
163
+ const api = chainService.getEvmApi(chain);
164
+ Promise.race([api.isReady, new Promise((resolve, reject) => createTimeout(() => reject(new Error('Timeout'))))]).then(resolve).catch(reject);
165
+ });
166
+ })]);
158
167
  const api = _api.api;
159
- if (extrinsicHash) {
168
+ if (extrinsicHash && (0, _util.isHex)(extrinsicHash)) {
160
169
  const transactionReceipt = await api.eth.getTransactionReceipt(extrinsicHash);
161
170
  return {
162
171
  ...result,
163
172
  status: transactionReceipt.status ? HistoryRecoverStatus.SUCCESS : HistoryRecoverStatus.FAILED
164
173
  };
165
174
  } else {
166
- if (!nonce || !startBlock) {
175
+ if (nonce === undefined || startBlock === undefined) {
167
176
  console.log(`Fail to find extrinsic for ${address} on ${chain}: With nonce ${nonce || 'undefined'} from block ${startBlock || 'undefined'}`);
168
177
  return {
169
178
  ...result,