@subwallet/extension-base 1.1.32-beta.0 → 1.1.33-beta.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 (43) hide show
  1. package/background/KoniTypes.d.ts +1 -0
  2. package/background/KoniTypes.js +1 -0
  3. package/cjs/background/KoniTypes.js +1 -0
  4. package/cjs/koni/api/staking/bonding/amplitude.js +97 -62
  5. package/cjs/koni/api/staking/paraChain.js +31 -5
  6. package/cjs/koni/api/xcm/xTokens.js +1 -1
  7. package/cjs/koni/background/handlers/Tabs.js +19 -2
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/chain-service/constants.js +3 -2
  10. package/cjs/services/earning-service/constants/chains.js +3 -2
  11. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +2 -2
  12. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +110 -65
  13. package/cjs/services/earning-service/service.js +32 -12
  14. package/cjs/services/history-service/index.js +12 -8
  15. package/cjs/services/transaction-service/index.js +62 -13
  16. package/cjs/utils/fetchEvmChainInfo.js +20 -0
  17. package/cjs/utils/index.js +24 -0
  18. package/koni/api/staking/bonding/amplitude.d.ts +1 -1
  19. package/koni/api/staking/bonding/amplitude.js +97 -62
  20. package/koni/api/staking/bonding/utils.d.ts +4 -0
  21. package/koni/api/staking/paraChain.js +31 -5
  22. package/koni/api/xcm/xTokens.js +1 -1
  23. package/koni/background/handlers/Tabs.js +20 -3
  24. package/package.json +11 -6
  25. package/packageInfo.js +1 -1
  26. package/services/chain-service/constants.js +3 -2
  27. package/services/earning-service/constants/chains.d.ts +1 -0
  28. package/services/earning-service/constants/chains.js +3 -2
  29. package/services/earning-service/handlers/liquid-staking/bifrost.js +2 -2
  30. package/services/earning-service/handlers/native-staking/amplitude.d.ts +1 -1
  31. package/services/earning-service/handlers/native-staking/amplitude.js +110 -65
  32. package/services/earning-service/service.d.ts +2 -1
  33. package/services/earning-service/service.js +33 -13
  34. package/services/event-service/types.d.ts +1 -0
  35. package/services/history-service/index.js +12 -8
  36. package/services/transaction-service/index.d.ts +5 -0
  37. package/services/transaction-service/index.js +49 -1
  38. package/services/transaction-service/types.d.ts +1 -0
  39. package/types/yield/info/chain/info.d.ts +1 -0
  40. package/utils/fetchEvmChainInfo.d.ts +17 -0
  41. package/utils/fetchEvmChainInfo.js +14 -0
  42. package/utils/index.d.ts +2 -0
  43. package/utils/index.js +3 -1
@@ -155,7 +155,7 @@ class EarningService {
155
155
  });
156
156
  }
157
157
  async loadData() {
158
- await this.getYieldPoolInfoFromDBAndOnline();
158
+ await this.getYieldPoolInfoFromDB();
159
159
  await this.getYieldPositionFromDB();
160
160
  }
161
161
  persistData() {
@@ -265,18 +265,12 @@ class EarningService {
265
265
  });
266
266
  };
267
267
  }
268
- async getYieldPoolInfoFromDBAndOnline() {
268
+ async getYieldPoolInfoFromDB() {
269
269
  // Get online pool data
270
- const yieldPoolInfo = await Promise.race([fetchPoolsData(), new Promise(resolve => {
271
- setTimeout(() => {
272
- resolve({});
273
- }, 1200);
274
- })]);
270
+ const yieldPoolInfo = {};
275
271
  const existedYieldPoolInfo = await this.dbService.getYieldPools();
276
272
  existedYieldPoolInfo.forEach(info => {
277
- if (!yieldPoolInfo[info.slug]) {
278
- yieldPoolInfo[info.slug] = info;
279
- }
273
+ yieldPoolInfo[info.slug] = info;
280
274
  });
281
275
  this.yieldPoolInfoSubject.next(yieldPoolInfo);
282
276
  }
@@ -297,7 +291,11 @@ class EarningService {
297
291
 
298
292
  // Update yield pool info
299
293
  queue.forEach(item => {
300
- yieldPoolInfo[item.slug] = item;
294
+ const existed = yieldPoolInfo[item.slug];
295
+ if (item.statistic && (!(existed !== null && existed !== void 0 && existed.lastUpdated) || existed.lastUpdated < ((item === null || item === void 0 ? void 0 : item.lastUpdated) || 0))) {
296
+ // Only update item has statistic information
297
+ yieldPoolInfo[item.slug] = item;
298
+ }
301
299
  });
302
300
  this.yieldPoolInfoSubject.next(yieldPoolInfo);
303
301
 
@@ -305,13 +303,35 @@ class EarningService {
305
303
  this.dbService.updateYieldPoolsStore(queue).catch(console.warn);
306
304
  }, 300, 900);
307
305
  }
306
+ async fetchingPoolsInfoOnline() {
307
+ const onlineData = await Promise.race([fetchPoolsData(), new Promise(resolve => {
308
+ setTimeout(() => {
309
+ resolve({});
310
+ }, 1800);
311
+ })]);
312
+ Object.values(onlineData).forEach(item => {
313
+ this.updateYieldPoolInfo(item);
314
+ });
315
+ }
308
316
  async runSubscribePoolsInfo() {
309
317
  await this.eventService.waitChainReady;
310
318
  this.runUnsubscribePoolsInfo();
319
+
320
+ // Fetching online data
321
+ await this.fetchingPoolsInfoOnline();
322
+ const interval = setInterval(() => {
323
+ this.fetchingPoolsInfoOnline().catch(console.error);
324
+ }, _constants.CRON_REFRESH_CHAIN_STAKING_METADATA);
325
+
326
+ // Fetching from chains
311
327
  this.subscribePoolsInfo(data => {
328
+ data.lastUpdated = Date.now();
312
329
  this.updateYieldPoolInfo(data);
313
330
  }).then(rs => {
314
- this.yieldPoolsInfoUnsub = rs;
331
+ this.yieldPoolsInfoUnsub = () => {
332
+ rs();
333
+ clearInterval(interval);
334
+ };
315
335
  }).catch(console.error);
316
336
  }
317
337
  runUnsubscribePoolsInfo() {
@@ -173,14 +173,18 @@ class HistoryService {
173
173
 
174
174
  // Insert history with check override origin 'app'
175
175
  async addHistoryItems(historyItems) {
176
- // Prevent override record with original is 'app'
177
- const appRecords = this.historySubject.value.filter(item => item.origin === 'app');
178
- const excludeKeys = appRecords.map(item => {
179
- return `${item.chain}-${item.extrinsicHash}`;
180
- });
181
- const updateRecords = historyItems.filter(item => {
182
- const key = `${item.chain}-${item.extrinsicHash}`;
183
- return item.origin === 'app' || !excludeKeys.includes(key);
176
+ const updateRecords = [];
177
+ const appItems = this.historySubject.value.filter(i => i.origin === 'app');
178
+ historyItems.forEach(item => {
179
+ const needUpdateItem = appItems.find(item_ => item_.extrinsicHash === item.extrinsicHash && item.chain === item_.chain && item.address === item_.address);
180
+ if (needUpdateItem) {
181
+ updateRecords.push({
182
+ ...needUpdateItem,
183
+ status: item.status
184
+ });
185
+ return;
186
+ }
187
+ updateRecords.push(item);
184
188
  });
185
189
  await this.dbService.upsertHistory(updateRecords);
186
190
  this.historySubject.next(await this.dbService.getHistories());
@@ -42,6 +42,10 @@ class TransactionService {
42
42
  }
43
43
  constructor(state) {
44
44
  this.state = state;
45
+ this.eventService = state.eventService;
46
+ this.historyService = state.historyService;
47
+ this.notificationService = state.notificationService;
48
+ this.chainService = state.chainService;
45
49
  }
46
50
  get allTransactions() {
47
51
  return Object.values(this.transactions);
@@ -297,6 +301,12 @@ class TransactionService {
297
301
  errors: [...data.errors, new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.INTERNAL_ERROR)]
298
302
  });
299
303
  });
304
+ emitter.on('timeout', data => {
305
+ this.onTimeOut({
306
+ ...data,
307
+ errors: [...data.errors, new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.TIMEOUT)]
308
+ });
309
+ });
300
310
 
301
311
  // Todo: handle any event with transaction.eventsHandler
302
312
 
@@ -800,6 +810,45 @@ class TransactionService {
800
810
  }
801
811
  this.state.eventService.emit('transaction.failed', transaction);
802
812
  }
813
+ onTimeOut(_ref6) {
814
+ let {
815
+ blockHash,
816
+ blockNumber,
817
+ errors,
818
+ extrinsicHash,
819
+ id
820
+ } = _ref6;
821
+ const transaction = this.getTransaction(id);
822
+ const nextStatus = _KoniTypes.ExtrinsicStatus.TIMEOUT;
823
+ if (transaction) {
824
+ this.updateTransaction(id, {
825
+ status: nextStatus,
826
+ errors,
827
+ extrinsicHash
828
+ });
829
+ this.historyService.updateHistoryByExtrinsicHash(transaction.extrinsicHash, {
830
+ extrinsicHash: extrinsicHash || transaction.extrinsicHash,
831
+ status: nextStatus,
832
+ blockNumber: blockNumber || 0,
833
+ blockHash: blockHash || ''
834
+ }).catch(console.error);
835
+ const info = (0, _util.isHex)(transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash) ? transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash : (0, _helpers.getBaseTransactionInfo)(transaction, this.chainService.getChainInfoMap());
836
+ this.notificationService.notify({
837
+ type: _KoniTypes.NotificationType.ERROR,
838
+ title: (0, _i18next.t)('Transaction timed out'),
839
+ message: (0, _i18next.t)('Transaction {{info}} timed out', {
840
+ replace: {
841
+ info
842
+ }
843
+ }),
844
+ action: {
845
+ url: this.getTransactionLink(id)
846
+ },
847
+ notifyViaBrowser: true
848
+ });
849
+ }
850
+ this.eventService.emit('transaction.timeout', transaction);
851
+ }
803
852
  generateHashPayload(chain, transaction) {
804
853
  var _transaction$nonce;
805
854
  const chainInfo = this.state.chainService.getChainInfoByKey(chain);
@@ -814,7 +863,7 @@ class TransactionService {
814
863
  };
815
864
  return _ethers.ethers.Transaction.from(txObject).unsignedSerialized;
816
865
  }
817
- async signAndSendEvmTransaction(_ref6) {
866
+ async signAndSendEvmTransaction(_ref7) {
818
867
  var _payload$nonce;
819
868
  let {
820
869
  address,
@@ -822,7 +871,7 @@ class TransactionService {
822
871
  id,
823
872
  transaction,
824
873
  url
825
- } = _ref6;
874
+ } = _ref7;
826
875
  const payload = transaction;
827
876
  const evmApi = this.state.chainService.getEvmApi(chain);
828
877
  const chainInfo = this.state.chainService.getChainInfoByKey(chain);
@@ -890,11 +939,11 @@ class TransactionService {
890
939
  extrinsicHash: id
891
940
  };
892
941
  if (isInjected) {
893
- this.state.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmWatchTransactionRequest', payload, {}).then(async _ref7 => {
942
+ this.state.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmWatchTransactionRequest', payload, {}).then(async _ref8 => {
894
943
  let {
895
944
  isApproved,
896
945
  payload
897
- } = _ref7;
946
+ } = _ref8;
898
947
  if (isApproved) {
899
948
  if (!payload) {
900
949
  throw new _EvmProviderError.EvmProviderError(_KoniTypes.EvmProviderErrorType.UNAUTHORIZED, 'Bad signature');
@@ -955,11 +1004,11 @@ class TransactionService {
955
1004
  emitter.emit('error', eventData);
956
1005
  });
957
1006
  } else {
958
- this.state.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(async _ref8 => {
1007
+ this.state.requestService.addConfirmation(id, url || _constants2.EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(async _ref9 => {
959
1008
  let {
960
1009
  isApproved,
961
1010
  payload
962
- } = _ref8;
1011
+ } = _ref9;
963
1012
  if (isApproved) {
964
1013
  let signedTransaction;
965
1014
  if (!payload) {
@@ -1015,14 +1064,14 @@ class TransactionService {
1015
1064
  }
1016
1065
  return emitter;
1017
1066
  }
1018
- signAndSendSubstrateTransaction(_ref9) {
1067
+ signAndSendSubstrateTransaction(_ref10) {
1019
1068
  let {
1020
1069
  address,
1021
1070
  chain,
1022
1071
  id,
1023
1072
  transaction,
1024
1073
  url
1025
- } = _ref9;
1074
+ } = _ref10;
1026
1075
  const emitter = new _eventemitter.default();
1027
1076
  const eventData = {
1028
1077
  id,
@@ -1068,20 +1117,20 @@ class TransactionService {
1068
1117
  eventData.extrinsicHash = txState.txHash.toHex();
1069
1118
  eventData.eventLogs = txState.events;
1070
1119
  // TODO: push block hash and block number into eventData
1071
- txState.events.filter(_ref10 => {
1120
+ txState.events.filter(_ref11 => {
1072
1121
  let {
1073
1122
  event: {
1074
1123
  section
1075
1124
  }
1076
- } = _ref10;
1125
+ } = _ref11;
1077
1126
  return section === 'system';
1078
- }).forEach(_ref11 => {
1127
+ }).forEach(_ref12 => {
1079
1128
  let {
1080
1129
  event: {
1081
1130
  data: [error],
1082
1131
  method
1083
1132
  }
1084
- } = _ref11;
1133
+ } = _ref12;
1085
1134
  if (method === 'ExtrinsicFailed') {
1086
1135
  eventData.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.SEND_TRANSACTION_FAILED, error.toString()));
1087
1136
  emitter.emit('error', eventData);
@@ -1106,7 +1155,7 @@ class TransactionService {
1106
1155
  const transaction = this.getTransaction(eventData.id);
1107
1156
  if (transaction.status !== _KoniTypes.ExtrinsicStatus.SUCCESS && transaction.status !== _KoniTypes.ExtrinsicStatus.FAIL) {
1108
1157
  eventData.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.TIMEOUT, (0, _i18next.t)('Transaction timeout')));
1109
- emitter.emit('error', eventData);
1158
+ emitter.emit('timeout', eventData);
1110
1159
  clearTimeout(timeout);
1111
1160
  }
1112
1161
  }, _constants3.TRANSACTION_TIMEOUT);
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getEVMChainInfo = getEVMChainInfo;
7
+ // Copyright 2019-2022 @subwallet/extension-base
8
+ // SPDX-License-Identifier: Apache-2.0
9
+
10
+ const onlineMap = {};
11
+ async function getEVMChainInfo(chainId) {
12
+ if (Object.keys(onlineMap).length === 0) {
13
+ const rs = await fetch('https://chainid.network/chains.json');
14
+ const data = await rs.json();
15
+ data.forEach(item => {
16
+ onlineMap[item.chainId] = item;
17
+ });
18
+ }
19
+ return onlineMap[chainId];
20
+ }
@@ -190,6 +190,30 @@ Object.keys(_object).forEach(function (key) {
190
190
  }
191
191
  });
192
192
  });
193
+ var _fetchStaticData = require("./fetchStaticData");
194
+ Object.keys(_fetchStaticData).forEach(function (key) {
195
+ if (key === "default" || key === "__esModule") return;
196
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
197
+ if (key in exports && exports[key] === _fetchStaticData[key]) return;
198
+ Object.defineProperty(exports, key, {
199
+ enumerable: true,
200
+ get: function () {
201
+ return _fetchStaticData[key];
202
+ }
203
+ });
204
+ });
205
+ var _fetchEvmChainInfo = require("./fetchEvmChainInfo");
206
+ Object.keys(_fetchEvmChainInfo).forEach(function (key) {
207
+ if (key === "default" || key === "__esModule") return;
208
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
209
+ if (key in exports && exports[key] === _fetchEvmChainInfo[key]) return;
210
+ Object.defineProperty(exports, key, {
211
+ enumerable: true,
212
+ get: function () {
213
+ return _fetchEvmChainInfo[key];
214
+ }
215
+ });
216
+ });
193
217
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
194
218
  // SPDX-License-Identifier: Apache-2.0
195
219
 
@@ -5,7 +5,7 @@ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/
5
5
  import { Codec } from '@polkadot/types/types';
6
6
  export declare function subscribeAmplitudeStakingMetadata(chain: string, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
7
7
  export declare function getAmplitudeStakingMetadata(chain: string, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
8
- export declare function subscribeAmplitudeNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, delegatorState: ParachainStakingStakeOption, unstakingInfo: Record<string, number>): Promise<NominatorMetadata>;
8
+ export declare function subscribeAmplitudeNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, delegatorState: ParachainStakingStakeOption[], unstakingInfo: Record<string, number>): Promise<NominatorMetadata>;
9
9
  /**
10
10
  * Deprecated
11
11
  * */
@@ -4,6 +4,7 @@
4
4
  import { StakingType } from '@subwallet/extension-base/background/KoniTypes';
5
5
  import { getBondedValidators, getEarningStatusByNominations, isUnstakeAll } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
6
6
  import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
7
+ import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
7
8
  import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
8
9
  import { EarningStatus, UnstakingStatus } from '@subwallet/extension-base/types';
9
10
  import { parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
@@ -18,7 +19,7 @@ export function subscribeAmplitudeStakingMetadata(chain, substrateApi, callback)
18
19
  const unstakingDelay = substrateApi.api.consts.parachainStaking.stakeDuration.toString();
19
20
  const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
20
21
  const blockPerRound = parseFloat(_blockPerRound);
21
- const blockDuration = (_STAKING_ERA_LENGTH_MAP[chain] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
22
+ const blockDuration = (_STAKING_ERA_LENGTH_MAP[chain] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound;
22
23
  const unstakingPeriod = blockDuration * parseInt(unstakingDelay);
23
24
  callback(chain, {
24
25
  chain,
@@ -60,46 +61,52 @@ export async function subscribeAmplitudeNominatorMetadata(chainInfo, address, su
60
61
  const nominationList = [];
61
62
  const unstakingList = [];
62
63
  const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
64
+ const hasUnstakingInfo = unstakingInfo && Object.values(unstakingInfo).length > 0;
63
65
  let activeStake = '0';
64
66
  if (delegatorState) {
65
67
  // delegatorState can be null while unstaking all
66
- const [identity] = await parseIdentity(substrateApi, delegatorState.owner);
67
- activeStake = delegatorState.amount.toString();
68
- const bnActiveStake = new BN(activeStake);
69
- let delegationStatus = EarningStatus.NOT_EARNING;
70
- if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegatorStake))) {
71
- delegationStatus = EarningStatus.EARNING_REWARD;
68
+ const identityPromises = delegatorState.map(delegate => parseIdentity(substrateApi, delegate.owner));
69
+ const identities = await Promise.all(identityPromises);
70
+ for (let i = 0; i < delegatorState.length; i++) {
71
+ const delegate = delegatorState[i];
72
+ const [identity] = identities[i];
73
+ activeStake = delegate.amount.toString();
74
+ const bnActiveStake = new BN(activeStake);
75
+ let delegationStatus = EarningStatus.NOT_EARNING;
76
+ if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegatorStake))) {
77
+ delegationStatus = EarningStatus.EARNING_REWARD;
78
+ }
79
+ nominationList.push({
80
+ status: delegationStatus,
81
+ chain: chainInfo.slug,
82
+ validatorAddress: delegate.owner,
83
+ activeStake: delegate.amount.toString(),
84
+ validatorMinStake: '0',
85
+ hasUnstaking: hasUnstakingInfo,
86
+ validatorIdentity: identity
87
+ });
72
88
  }
73
- nominationList.push({
74
- status: delegationStatus,
75
- chain: chainInfo.slug,
76
- validatorAddress: delegatorState.owner,
77
- activeStake: delegatorState.amount.toString(),
78
- validatorMinStake: '0',
79
- hasUnstaking: !!unstakingInfo && Object.values(unstakingInfo).length > 0,
80
- validatorIdentity: identity
81
- });
82
- }
83
- if (unstakingInfo && Object.values(unstakingInfo).length > 0) {
84
- const _currentBlockInfo = await substrateApi.api.rpc.chain.getHeader();
85
- const currentBlockInfo = _currentBlockInfo.toPrimitive();
86
- const currentBlockNumber = currentBlockInfo.number;
87
- const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
88
- const blockPerRound = parseFloat(_blockPerRound);
89
- const nearestUnstakingBlock = Object.keys(unstakingInfo)[0];
90
- const nearestUnstakingAmount = Object.values(unstakingInfo)[0];
91
- const blockDuration = (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
89
+ if (hasUnstakingInfo) {
90
+ const _currentBlockInfo = await substrateApi.api.rpc.chain.getHeader();
91
+ const currentBlockInfo = _currentBlockInfo.toPrimitive();
92
+ const currentBlockNumber = currentBlockInfo.number;
93
+ const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
94
+ const blockPerRound = parseFloat(_blockPerRound);
95
+ for (const [unstakingBlock, unstakingAmount] of Object.entries(unstakingInfo)) {
96
+ const blockDuration = (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
92
97
 
93
- const isClaimable = parseInt(nearestUnstakingBlock) - currentBlockNumber < 0;
94
- const remainingBlock = parseInt(nearestUnstakingBlock) - currentBlockNumber;
95
- const waitingTime = remainingBlock * blockDuration;
96
- unstakingList.push({
97
- chain: chainInfo.slug,
98
- status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
99
- claimable: nearestUnstakingAmount.toString(),
100
- waitingTime,
101
- validatorAddress: (delegatorState === null || delegatorState === void 0 ? void 0 : delegatorState.owner) || undefined
102
- });
98
+ const isClaimable = parseInt(unstakingBlock) - currentBlockNumber < 0;
99
+ const remainingBlock = parseInt(unstakingBlock) - currentBlockNumber;
100
+ const waitingTime = remainingBlock * blockDuration;
101
+ unstakingList.push({
102
+ chain: chainInfo.slug,
103
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
104
+ claimable: unstakingAmount.toString(),
105
+ waitingTime,
106
+ validatorAddress: undefined
107
+ });
108
+ }
109
+ }
103
110
  }
104
111
  const stakingStatus = getEarningStatusByNominations(new BN(activeStake), nominationList);
105
112
  return {
@@ -196,33 +203,61 @@ export async function getAmplitudeNominatorMetadata(chainInfo, address, substrat
196
203
  }
197
204
  export async function getAmplitudeCollatorsInfo(chain, substrateApi) {
198
205
  const chainApi = await substrateApi.isReady;
199
- const [_allCollators, _inflationConfig] = await Promise.all([chainApi.api.query.parachainStaking.candidatePool.entries(), chainApi.api.query.parachainStaking.inflationConfig()]);
200
- const maxDelegatorsPerCollator = chainApi.api.consts.parachainStaking.maxDelegatorsPerCollator.toString();
201
- const inflationConfig = _inflationConfig.toHuman();
202
- const rawDelegatorReturn = inflationConfig.delegator.rewardRate.annual;
203
- const delegatorReturn = parseFloat(rawDelegatorReturn.split('%')[0]);
204
- const allCollators = [];
205
- for (const _collator of _allCollators) {
206
- const collatorInfo = _collator[1].toPrimitive();
207
- const bnTotalStake = new BN(collatorInfo.total);
208
- const bnOwnStake = new BN(collatorInfo.stake);
209
- const bnOtherStake = bnTotalStake.sub(bnOwnStake);
210
- allCollators.push({
211
- address: collatorInfo.id,
212
- totalStake: bnTotalStake.toString(),
213
- ownStake: bnOwnStake.toString(),
214
- otherStake: bnOtherStake.toString(),
215
- nominatorCount: collatorInfo.delegators.length,
216
- commission: 0,
217
- expectedReturn: delegatorReturn,
218
- blocked: false,
219
- isVerified: false,
220
- minBond: '0',
221
- chain,
222
- isCrowded: collatorInfo.delegators.length >= parseInt(maxDelegatorsPerCollator)
223
- });
206
+
207
+ // Noted: Krest do not have reward
208
+ if (_STAKING_CHAIN_GROUP.krest_network.includes(chain)) {
209
+ const _allCollators = await chainApi.api.query.parachainStaking.candidatePool.entries();
210
+ const maxDelegatorsPerCollator = chainApi.api.consts.parachainStaking.maxDelegatorsPerCollator.toString();
211
+ const allCollators = [];
212
+ for (const _collator of _allCollators) {
213
+ const collatorInfo = _collator[1].toPrimitive();
214
+ const bnTotalStake = new BN(collatorInfo.total);
215
+ const bnOwnStake = new BN(collatorInfo.stake);
216
+ const bnOtherStake = bnTotalStake.sub(bnOwnStake);
217
+ allCollators.push({
218
+ address: collatorInfo.id,
219
+ totalStake: bnTotalStake.toString(),
220
+ ownStake: bnOwnStake.toString(),
221
+ otherStake: bnOtherStake.toString(),
222
+ nominatorCount: collatorInfo.delegators.length,
223
+ commission: 0,
224
+ blocked: false,
225
+ isVerified: false,
226
+ minBond: '0',
227
+ chain,
228
+ isCrowded: collatorInfo.delegators.length >= parseInt(maxDelegatorsPerCollator)
229
+ });
230
+ }
231
+ return allCollators;
232
+ } else {
233
+ const [_allCollators, _inflationConfig] = await Promise.all([chainApi.api.query.parachainStaking.candidatePool.entries(), chainApi.api.query.parachainStaking.inflationConfig()]);
234
+ const maxDelegatorsPerCollator = chainApi.api.consts.parachainStaking.maxDelegatorsPerCollator.toString();
235
+ const inflationConfig = _inflationConfig.toHuman();
236
+ const rawDelegatorReturn = inflationConfig.delegator.rewardRate.annual;
237
+ const delegatorReturn = parseFloat(rawDelegatorReturn.split('%')[0]);
238
+ const allCollators = [];
239
+ for (const _collator of _allCollators) {
240
+ const collatorInfo = _collator[1].toPrimitive();
241
+ const bnTotalStake = new BN(collatorInfo.total);
242
+ const bnOwnStake = new BN(collatorInfo.stake);
243
+ const bnOtherStake = bnTotalStake.sub(bnOwnStake);
244
+ allCollators.push({
245
+ address: collatorInfo.id,
246
+ totalStake: bnTotalStake.toString(),
247
+ ownStake: bnOwnStake.toString(),
248
+ otherStake: bnOtherStake.toString(),
249
+ nominatorCount: collatorInfo.delegators.length,
250
+ commission: 0,
251
+ expectedReturn: delegatorReturn,
252
+ blocked: false,
253
+ isVerified: false,
254
+ minBond: '0',
255
+ chain,
256
+ isCrowded: collatorInfo.delegators.length >= parseInt(maxDelegatorsPerCollator)
257
+ });
258
+ }
259
+ return allCollators;
224
260
  }
225
- return allCollators;
226
261
  }
227
262
  export async function getAmplitudeBondingExtrinsic(substrateApi, amount, selectedValidatorInfo, nominatorMetadata) {
228
263
  const chainApi = await substrateApi.isReady;
@@ -33,6 +33,10 @@ export interface ParachainStakingStakeOption {
33
33
  owner: string;
34
34
  amount: number;
35
35
  }
36
+ export interface KrestDelegateState {
37
+ delegations: ParachainStakingStakeOption[];
38
+ total: string;
39
+ }
36
40
  export interface ParachainStakingCandidateMetadata {
37
41
  bond: string;
38
42
  delegationCount: number;
@@ -13,7 +13,15 @@ import { BN, BN_ZERO } from '@polkadot/util';
13
13
  import { isEthereumAddress } from '@polkadot/util-crypto';
14
14
  function getSingleStakingAmplitude(substrateApi, address, chainInfoMap, chain, stakingCallback, nominatorStateCallback) {
15
15
  return substrateApi.api.queryMulti([[substrateApi.api.query.parachainStaking.delegatorState, address], [substrateApi.api.query.parachainStaking.unstaking, address]], async ([_delegatorState, _unstaking]) => {
16
- const delegatorState = _delegatorState.toPrimitive();
16
+ let delegatorState = [];
17
+ if (_STAKING_CHAIN_GROUP.krest_network.includes(chain)) {
18
+ const krestDelegatorState = _delegatorState.toPrimitive();
19
+ const delegates = krestDelegatorState === null || krestDelegatorState === void 0 ? void 0 : krestDelegatorState.delegations;
20
+ delegatorState = delegatorState.concat(delegates);
21
+ } else {
22
+ const delegate = _delegatorState.toPrimitive();
23
+ delegatorState.push(delegate);
24
+ }
17
25
  const unstakingInfo = _unstaking.toPrimitive();
18
26
  const {
19
27
  symbol
@@ -42,8 +50,13 @@ function getSingleStakingAmplitude(substrateApi, address, chainInfoMap, chain, s
42
50
  unstakings: []
43
51
  });
44
52
  } else {
45
- const activeBalance = delegatorState ? new BN(delegatorState.amount.toString()) : BN_ZERO;
53
+ let activeBalance = BN_ZERO;
46
54
  let unstakingBalance = BN_ZERO;
55
+ for (const delegate of delegatorState) {
56
+ var _delegate$amount;
57
+ const amount = new BN((_delegate$amount = delegate.amount) === null || _delegate$amount === void 0 ? void 0 : _delegate$amount.toString());
58
+ activeBalance = activeBalance.add(amount);
59
+ }
47
60
  if (unstakingInfo) {
48
61
  Object.values(unstakingInfo).forEach(unstakingAmount => {
49
62
  const bnUnstakingAmount = new BN(unstakingAmount.toString());
@@ -78,7 +91,15 @@ function getMultiStakingAmplitude(substrateApi, useAddresses, chainInfoMap, chai
78
91
  const _unstakingStates = await substrateApi.api.query.parachainStaking.unstaking.multi(useAddresses);
79
92
  await Promise.all(ledgers.map(async (_delegatorState, i) => {
80
93
  const owner = reformatAddress(useAddresses[i], 42);
81
- const delegatorState = _delegatorState.toPrimitive();
94
+ let delegatorState = [];
95
+ if (_STAKING_CHAIN_GROUP.krest_network.includes(chain)) {
96
+ const krestDelegatorState = _delegatorState.toPrimitive();
97
+ const delegates = krestDelegatorState === null || krestDelegatorState === void 0 ? void 0 : krestDelegatorState.delegations;
98
+ delegatorState = delegatorState.concat(delegates);
99
+ } else {
100
+ const delegate = _delegatorState.toPrimitive();
101
+ delegatorState.push(delegate);
102
+ }
82
103
  const unstakingInfo = _unstakingStates[i].toPrimitive();
83
104
  if (!delegatorState && !unstakingInfo) {
84
105
  stakingCallback(chain, {
@@ -103,8 +124,13 @@ function getMultiStakingAmplitude(substrateApi, useAddresses, chainInfoMap, chai
103
124
  unstakings: []
104
125
  });
105
126
  } else {
106
- const activeBalance = delegatorState ? new BN(delegatorState.amount.toString()) : BN_ZERO;
127
+ let activeBalance = BN_ZERO;
107
128
  let unstakingBalance = BN_ZERO;
129
+ for (const delegate of delegatorState) {
130
+ var _delegate$amount2;
131
+ const amount = new BN((_delegate$amount2 = delegate.amount) === null || _delegate$amount2 === void 0 ? void 0 : _delegate$amount2.toString());
132
+ activeBalance = activeBalance.add(amount);
133
+ }
108
134
  if (unstakingInfo) {
109
135
  Object.values(unstakingInfo).forEach(unstakingAmount => {
110
136
  const bnUnstakingAmount = new BN(unstakingAmount.toString());
@@ -150,7 +176,7 @@ export async function getAmplitudeUnclaimedStakingReward(substrateApiMap, addres
150
176
  });
151
177
  const unclaimedRewardList = [];
152
178
  await Promise.all(chains.map(async chain => {
153
- if (_STAKING_CHAIN_GROUP.amplitude.includes(chain) && !_STAKING_CHAIN_GROUP.kilt.includes(chain)) {
179
+ if (_STAKING_CHAIN_GROUP.amplitude.includes(chain) && !_STAKING_CHAIN_GROUP.kilt.includes(chain) && !_STAKING_CHAIN_GROUP.krest_network.includes(chain)) {
154
180
  const networkInfo = networks[chain];
155
181
  const apiProps = await substrateApiMap[chain].isReady;
156
182
  await Promise.all(useAddresses.map(async address => {
@@ -19,6 +19,6 @@ function getCurrencyId(tokenInfo) {
19
19
  }
20
20
  export function getExtrinsicByXtokensPallet(tokenInfo, originChainInfo, destinationChainInfo, recipientAddress, value, api) {
21
21
  const weightParam = ['pioneer'].includes(originChainInfo.slug) ? FOUR_INSTRUCTIONS_WEIGHT : getDestWeight();
22
- const destVersion = ['moonbeam', 'moonriver', 'bifrost_dot', 'interlay', 'hydradx_main', 'acala', 'parallel', 'astar', 'shiden', 'centrifuge'].includes(originChainInfo.slug) ? 'V3' : undefined;
22
+ const destVersion = ['moonbeam', 'moonriver', 'bifrost_dot', 'interlay', 'hydradx_main', 'acala', 'parallel', 'astar', 'shiden', 'centrifuge', 'manta_network'].includes(originChainInfo.slug) ? 'V3' : undefined;
23
23
  return api.tx.xTokens.transfer(getCurrencyId(tokenInfo), value, getDestMultilocation(destinationChainInfo, recipientAddress, destVersion), weightParam);
24
24
  }