@subwallet/extension-base 1.2.23-0 → 1.2.24-1

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 (97) hide show
  1. package/background/KoniTypes.d.ts +14 -0
  2. package/cjs/constants/index.js +4 -1
  3. package/cjs/core/substrate/assets-pallet.js +35 -0
  4. package/cjs/core/substrate/foreign-asset-pallet.js +13 -3
  5. package/cjs/core/substrate/nominationpools-pallet.js +4 -6
  6. package/cjs/core/substrate/ormlTokens-pallet.js +24 -0
  7. package/cjs/core/substrate/system-pallet.js +16 -18
  8. package/cjs/core/substrate/tokens-pallet.js +24 -0
  9. package/cjs/core/substrate/types.js +19 -0
  10. package/cjs/core/substrate/xcm-parser.js +16 -2
  11. package/cjs/core/utils.js +31 -0
  12. package/cjs/koni/background/cron.js +10 -0
  13. package/cjs/koni/background/handlers/Extension.js +61 -5
  14. package/cjs/koni/background/handlers/State.js +3 -0
  15. package/cjs/packageInfo.js +1 -1
  16. package/cjs/services/balance-service/helpers/subscribe/substrate/equilibrium.js +2 -2
  17. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +120 -133
  18. package/cjs/services/balance-service/transfer/xcm/index.js +2 -1
  19. package/cjs/services/balance-service/transfer/xcm/polkadotXcm.js +1 -1
  20. package/cjs/services/balance-service/transfer/xcm/utils.js +3 -2
  21. package/cjs/services/chain-service/constants.js +1 -1
  22. package/cjs/services/chain-service/handler/SubstrateApi.js +128 -34
  23. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +26 -9
  24. package/cjs/services/chain-service/utils/index.js +5 -0
  25. package/cjs/services/migration-service/scripts/MigrateLedgerAccountV2.js +3 -3
  26. package/cjs/services/mkt-campaign-service/index.js +284 -0
  27. package/cjs/services/mkt-campaign-service/types.js +17 -0
  28. package/cjs/services/storage-service/DatabaseService.js +115 -0
  29. package/cjs/services/storage-service/db-stores/Balance.js +6 -0
  30. package/cjs/services/storage-service/db-stores/Crowdloan.js +8 -0
  31. package/cjs/services/storage-service/db-stores/Nft.js +12 -0
  32. package/cjs/services/storage-service/db-stores/NftCollection.js +11 -0
  33. package/cjs/services/storage-service/db-stores/YieldPositionStore.js +6 -0
  34. package/constants/index.d.ts +1 -0
  35. package/constants/index.js +1 -0
  36. package/core/substrate/assets-pallet.d.ts +4 -0
  37. package/core/substrate/assets-pallet.js +28 -0
  38. package/core/substrate/foreign-asset-pallet.d.ts +4 -8
  39. package/core/substrate/foreign-asset-pallet.js +13 -3
  40. package/core/substrate/nominationpools-pallet.d.ts +4 -10
  41. package/core/substrate/nominationpools-pallet.js +4 -5
  42. package/core/substrate/ormlTokens-pallet.d.ts +4 -0
  43. package/core/substrate/ormlTokens-pallet.js +17 -0
  44. package/core/substrate/system-pallet.d.ts +4 -24
  45. package/core/substrate/system-pallet.js +16 -21
  46. package/core/substrate/tokens-pallet.d.ts +5 -0
  47. package/core/substrate/tokens-pallet.js +16 -0
  48. package/core/substrate/types.d.ts +43 -0
  49. package/core/substrate/types.js +12 -0
  50. package/core/substrate/xcm-parser.d.ts +1 -0
  51. package/core/substrate/xcm-parser.js +15 -2
  52. package/core/utils.d.ts +4 -0
  53. package/core/utils.js +23 -0
  54. package/koni/api/staking/bonding/relayChain.d.ts +1 -1
  55. package/koni/background/cron.d.ts +1 -0
  56. package/koni/background/cron.js +11 -1
  57. package/koni/background/handlers/Extension.d.ts +3 -0
  58. package/koni/background/handlers/Extension.js +61 -5
  59. package/koni/background/handlers/State.d.ts +4 -2
  60. package/koni/background/handlers/State.js +3 -0
  61. package/package.json +41 -6
  62. package/packageInfo.js +1 -1
  63. package/services/balance-service/helpers/subscribe/substrate/equilibrium.js +2 -2
  64. package/services/balance-service/helpers/subscribe/substrate/index.js +109 -121
  65. package/services/balance-service/transfer/xcm/index.d.ts +1 -1
  66. package/services/balance-service/transfer/xcm/index.js +2 -1
  67. package/services/balance-service/transfer/xcm/polkadotXcm.js +1 -1
  68. package/services/balance-service/transfer/xcm/utils.d.ts +1 -1
  69. package/services/balance-service/transfer/xcm/utils.js +3 -2
  70. package/services/chain-service/constants.js +1 -1
  71. package/services/chain-service/handler/SubstrateApi.d.ts +5 -7
  72. package/services/chain-service/handler/SubstrateApi.js +128 -35
  73. package/services/chain-service/handler/SubstrateChainHandler.d.ts +5 -6
  74. package/services/chain-service/handler/SubstrateChainHandler.js +26 -9
  75. package/services/chain-service/index.d.ts +3 -3
  76. package/services/chain-service/types.d.ts +22 -5
  77. package/services/chain-service/utils/index.d.ts +1 -0
  78. package/services/chain-service/utils/index.js +3 -0
  79. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -1
  80. package/services/migration-service/scripts/MigrateLedgerAccountV2.js +3 -3
  81. package/services/mkt-campaign-service/index.d.ts +30 -0
  82. package/services/mkt-campaign-service/index.js +275 -0
  83. package/services/mkt-campaign-service/types.d.ts +107 -0
  84. package/services/mkt-campaign-service/types.js +11 -0
  85. package/services/storage-service/DatabaseService.d.ts +5 -0
  86. package/services/storage-service/DatabaseService.js +116 -1
  87. package/services/storage-service/db-stores/Balance.d.ts +2 -0
  88. package/services/storage-service/db-stores/Balance.js +6 -0
  89. package/services/storage-service/db-stores/Crowdloan.d.ts +2 -0
  90. package/services/storage-service/db-stores/Crowdloan.js +8 -0
  91. package/services/storage-service/db-stores/Nft.d.ts +2 -0
  92. package/services/storage-service/db-stores/Nft.js +12 -0
  93. package/services/storage-service/db-stores/NftCollection.d.ts +1 -0
  94. package/services/storage-service/db-stores/NftCollection.js +11 -0
  95. package/services/storage-service/db-stores/YieldPositionStore.d.ts +2 -0
  96. package/services/storage-service/db-stores/YieldPositionStore.js +6 -0
  97. package/types/balance/index.d.ts +2 -3
@@ -0,0 +1,275 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { _getAssetDecimals, _getChainNativeTokenBasicInfo } from '@subwallet/extension-base/services/chain-service/utils';
5
+ import { MktCampaignConditionTypeValue } from '@subwallet/extension-base/services/mkt-campaign-service/types';
6
+ import { fetchStaticData, TARGET_ENV, wait } from '@subwallet/extension-base/utils';
7
+ import { keyring } from '@subwallet/ui-keyring';
8
+ import BigN from 'bignumber.js';
9
+ import { BehaviorSubject } from 'rxjs';
10
+ export default class MktCampaignService {
11
+ #state;
12
+ appPopupSubject = new BehaviorSubject([]);
13
+ appBannerSubject = new BehaviorSubject([]);
14
+ appConfirmationSubject = new BehaviorSubject([]);
15
+ constructor(state) {
16
+ this.#state = state;
17
+ this.appPopupSubject.next([]);
18
+ this.appBannerSubject.next([]);
19
+ this.appConfirmationSubject.next([]);
20
+ this.fetchPopupData().catch(e => {
21
+ console.error('Error on fetch popup', e);
22
+ });
23
+ this.fetchBannerData().catch(e => {
24
+ console.error('Error on fetch banner', e);
25
+ });
26
+ this.fetchConfirmationData().catch(e => {
27
+ console.error('Error on fetch confirmation', e);
28
+ });
29
+ }
30
+ fetchMktCampaignData(timeout = 10000) {
31
+ wait(timeout).finally(() => {
32
+ this.fetchPopupData().catch(console.error);
33
+ this.fetchBannerData().catch(console.error);
34
+ this.fetchConfirmationData().catch(console.error);
35
+ });
36
+ }
37
+ init() {
38
+ this.fetchMktCampaignData();
39
+ console.log('Mkt campaign service ready');
40
+ }
41
+ async fetchPopupData() {
42
+ const respAppPopupData = await fetchStaticData('app-popups');
43
+ const result = await this.handleMktCampaignData(respAppPopupData);
44
+ this.appPopupSubject.next(result);
45
+ }
46
+ async fetchBannerData() {
47
+ const respAppBannerData = await fetchStaticData('app-banners');
48
+ const result = await this.handleMktCampaignData(respAppBannerData);
49
+ this.appBannerSubject.next(result);
50
+ }
51
+ async fetchConfirmationData() {
52
+ const respAppConfirmationData = await fetchStaticData('app-confirmations');
53
+ const result = await this.handleMktCampaignData(respAppConfirmationData);
54
+ this.appConfirmationSubject.next(result);
55
+ }
56
+ subscribePopupsData(callback) {
57
+ return this.appPopupSubject.subscribe({
58
+ next: callback
59
+ });
60
+ }
61
+ subscribeBannersData(callback) {
62
+ return this.appBannerSubject.subscribe({
63
+ next: callback
64
+ });
65
+ }
66
+ subscribeConfirmationsData(callback) {
67
+ return this.appConfirmationSubject.subscribe({
68
+ next: callback
69
+ });
70
+ }
71
+ getAppPopupsData() {
72
+ return this.appPopupSubject.getValue();
73
+ }
74
+ getAppBannersData() {
75
+ return this.appBannerSubject.getValue();
76
+ }
77
+ getAppConfirmationsData() {
78
+ return this.appConfirmationSubject.getValue();
79
+ }
80
+ async handleMktCampaignData(data) {
81
+ const addresses = keyring.getPairs().map(pair => pair.address);
82
+ const allConditions = this.getAllConditions(data);
83
+ const conditionBalanceMap = await this.checkBalanceCondition(allConditions, addresses);
84
+ const conditionEarningMap = await this.checkEarningCondition(allConditions, addresses);
85
+ const conditionNftMap = await this.checkNftCondition(allConditions, addresses);
86
+ const conditionCrowdloanMap = await this.checkCrowdloanCondition(allConditions, addresses);
87
+ const conditionHasMoneyMap = await this.checkHasMoneyCondition(allConditions, addresses);
88
+
89
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
90
+ const conditionMap = Object.assign({}, conditionBalanceMap, conditionEarningMap, conditionNftMap, conditionCrowdloanMap, conditionHasMoneyMap);
91
+ const filteredData = this.checkActiveAndPlatformCondition(data);
92
+ return filteredData.filter(item => this.filterCampaignFunc(item, conditionMap));
93
+ }
94
+ checkActiveAndPlatformCondition(data) {
95
+ return data.filter(item => {
96
+ if (item.info) {
97
+ return this.checkCampaignExistTime(item.info) && item.info.platforms.includes(TARGET_ENV);
98
+ } else {
99
+ return true;
100
+ }
101
+ });
102
+ }
103
+ checkCampaignExistTime(info) {
104
+ if (info.start_time && info.stop_time) {
105
+ const now = new Date();
106
+ const startTime = new Date(info.start_time);
107
+ const endTime = new Date(info.stop_time);
108
+ return now >= startTime && now <= endTime;
109
+ } else {
110
+ return false;
111
+ }
112
+ }
113
+ async checkBalanceCondition(allConditions, addresses) {
114
+ var _allConditions$MktCam;
115
+ const allBalanceConditions = (_allConditions$MktCam = allConditions[MktCampaignConditionTypeValue.BALANCE]) === null || _allConditions$MktCam === void 0 ? void 0 : _allConditions$MktCam.map(condition => {
116
+ return JSON.parse(condition);
117
+ });
118
+ const allBalanceConditionPromises = [];
119
+ allBalanceConditions.forEach(balanceCondition => {
120
+ const decimals = _getAssetDecimals(this.#state.getAssetBySlug(balanceCondition.chain_asset));
121
+ const convertedValue = new BigN(balanceCondition.value).shiftedBy(decimals);
122
+ allBalanceConditionPromises.push(this.#state.dbService.checkBalanceByTokens([balanceCondition.chain_asset], balanceCondition.comparison, addresses, convertedValue.toString()));
123
+ });
124
+ const promiseBalanceResult = await Promise.all(allBalanceConditionPromises);
125
+ const conditionBalanceMap = {};
126
+ promiseBalanceResult.forEach((rs, i) => {
127
+ conditionBalanceMap[allConditions[MktCampaignConditionTypeValue.BALANCE][i]] = rs > 0;
128
+ });
129
+ return conditionBalanceMap;
130
+ }
131
+ async checkEarningCondition(allConditions, addresses) {
132
+ var _allConditions$MktCam2;
133
+ const allEarningConditions = (_allConditions$MktCam2 = allConditions[MktCampaignConditionTypeValue.EARNING]) === null || _allConditions$MktCam2 === void 0 ? void 0 : _allConditions$MktCam2.map(condition => {
134
+ return JSON.parse(condition);
135
+ });
136
+ const allEarningConditionPromises = [];
137
+ allEarningConditions.forEach(earningCondition => {
138
+ const poolSlugSplittedArr = earningCondition.pool_slug.split('___');
139
+ if (poolSlugSplittedArr[1] === 'liquid_staking') {
140
+ allEarningConditionPromises.push(new Promise(() => false));
141
+ }
142
+ const chain = earningCondition.pool_slug.split('___')[2];
143
+ const chainInfo = this.#state.getChainInfo(chain);
144
+ const {
145
+ decimals
146
+ } = _getChainNativeTokenBasicInfo(chainInfo);
147
+ const convertedValue = new BigN(earningCondition.value).shiftedBy(decimals);
148
+ allEarningConditionPromises.push(this.#state.dbService.checkEarningByTokens(earningCondition.pool_slug, earningCondition.comparison, addresses, convertedValue.toString()));
149
+ });
150
+ const promiseEarningResult = await Promise.all(allEarningConditionPromises);
151
+ const conditionEarningMap = {};
152
+ promiseEarningResult.forEach((rs, i) => {
153
+ conditionEarningMap[allConditions[MktCampaignConditionTypeValue.EARNING][i]] = rs > 0;
154
+ });
155
+ return conditionEarningMap;
156
+ }
157
+ async checkNftCondition(allConditions, addresses) {
158
+ var _allConditions$MktCam3;
159
+ const allNftConditions = (_allConditions$MktCam3 = allConditions[MktCampaignConditionTypeValue.NFT]) === null || _allConditions$MktCam3 === void 0 ? void 0 : _allConditions$MktCam3.map(condition => {
160
+ return JSON.parse(condition);
161
+ });
162
+ const allNftConditionPromises = [];
163
+ allNftConditions.forEach(nftCondition => {
164
+ allNftConditionPromises.push(this.#state.dbService.checkNftByTokens(nftCondition.chain, addresses, nftCondition.collection_id));
165
+ });
166
+ const promiseNftResult = await Promise.all(allNftConditionPromises);
167
+ const conditionNftMap = {};
168
+ promiseNftResult.forEach((rs, i) => {
169
+ conditionNftMap[allConditions[MktCampaignConditionTypeValue.NFT][i]] = rs > 0;
170
+ });
171
+ return conditionNftMap;
172
+ }
173
+ async checkCrowdloanCondition(allConditions, addresses) {
174
+ var _allConditions$MktCam4;
175
+ const allCrowdloanConditions = (_allConditions$MktCam4 = allConditions[MktCampaignConditionTypeValue.CROWDLOAN]) === null || _allConditions$MktCam4 === void 0 ? void 0 : _allConditions$MktCam4.map(condition => {
176
+ return JSON.parse(condition);
177
+ });
178
+ const allCrowdloanConditionPromises = [];
179
+ allCrowdloanConditions.forEach(crowdloanCondition => {
180
+ allCrowdloanConditionPromises.push(this.#state.dbService.checkCrowdloanByChain(crowdloanCondition.chain, addresses));
181
+ });
182
+ const promiseCrowdloanResult = await Promise.all(allCrowdloanConditionPromises);
183
+ const conditionCrowdloanMap = {};
184
+ promiseCrowdloanResult.forEach((rs, i) => {
185
+ conditionCrowdloanMap[allConditions[MktCampaignConditionTypeValue.CROWDLOAN][i]] = rs > 0;
186
+ });
187
+ return conditionCrowdloanMap;
188
+ }
189
+ async checkHasMoneyCondition(allConditions, addresses) {
190
+ const hasMoneyCondition = allConditions[MktCampaignConditionTypeValue.HAS_MONEY];
191
+ const allHasMoneyConditions = hasMoneyCondition === null || hasMoneyCondition === void 0 ? void 0 : hasMoneyCondition.map(condition => {
192
+ return JSON.parse(condition);
193
+ });
194
+ const allHasMoneyConditionPromises = [];
195
+ allHasMoneyConditions.forEach(hasMoneyCondition => {
196
+ allHasMoneyConditionPromises.push(this.#state.dbService.checkHasMoneyByTokens(hasMoneyCondition.has_money, addresses));
197
+ });
198
+ const promiseHasMoneyResult = await Promise.all(allHasMoneyConditionPromises);
199
+ const conditionHasMoneyMap = {};
200
+ promiseHasMoneyResult.forEach((rs, i) => {
201
+ conditionHasMoneyMap[hasMoneyCondition[i]] = rs > 0;
202
+ });
203
+ return conditionHasMoneyMap;
204
+ }
205
+ getAllConditions(respAppPopupData) {
206
+ const result = {
207
+ [MktCampaignConditionTypeValue.BALANCE]: [],
208
+ [MktCampaignConditionTypeValue.EARNING]: [],
209
+ [MktCampaignConditionTypeValue.CROWDLOAN]: [],
210
+ [MktCampaignConditionTypeValue.NFT]: [],
211
+ [MktCampaignConditionTypeValue.HAS_MONEY]: []
212
+ };
213
+ const getConditionByType = (campaignCondition, type) => {
214
+ const campaignConditionByType = campaignCondition[type];
215
+ campaignConditionByType === null || campaignConditionByType === void 0 ? void 0 : campaignConditionByType.forEach(condition => {
216
+ const conditionStringify = JSON.stringify(condition);
217
+ if (!result[type].includes(conditionStringify)) {
218
+ result[type].push(conditionStringify);
219
+ }
220
+ });
221
+ };
222
+ respAppPopupData.forEach(popup => {
223
+ const conditionKeys = Object.keys(popup.conditions);
224
+ if (conditionKeys && conditionKeys.length) {
225
+ conditionKeys.forEach(con => getConditionByType(popup.conditions, con));
226
+ }
227
+ });
228
+ return result;
229
+ }
230
+ filterCampaignFunc(item, conditionMap) {
231
+ const isPassValidation = [];
232
+ if (Object.values(item.conditions) && Object.values(item.conditions).length) {
233
+ const conditionBalance = Object.values(item.conditions[MktCampaignConditionTypeValue.BALANCE] || {});
234
+ const conditionEarning = Object.values(item.conditions[MktCampaignConditionTypeValue.EARNING] || {});
235
+ const conditionNft = Object.values(item.conditions[MktCampaignConditionTypeValue.NFT] || {});
236
+ const conditionCrowdloan = Object.values(item.conditions[MktCampaignConditionTypeValue.CROWDLOAN] || {});
237
+ const conditionHasMoney = Object.values(item.conditions[MktCampaignConditionTypeValue.HAS_MONEY] || {});
238
+ if (conditionBalance && conditionBalance.length) {
239
+ const isValidArr = conditionBalance.map(condition => {
240
+ return conditionMap[JSON.stringify(condition)];
241
+ });
242
+ isPassValidation.push(isValidArr.some(i => i));
243
+ }
244
+ if (conditionEarning && conditionEarning.length) {
245
+ const isValidArr = conditionEarning.map(condition => {
246
+ return conditionMap[JSON.stringify(condition)];
247
+ });
248
+ isPassValidation.push(isValidArr.some(i => i));
249
+ }
250
+ if (conditionNft && conditionNft.length) {
251
+ const isValidArr = conditionNft.map(condition => {
252
+ return conditionMap[JSON.stringify(condition)];
253
+ });
254
+ isPassValidation.push(isValidArr.some(i => i));
255
+ }
256
+ if (conditionCrowdloan && conditionCrowdloan.length) {
257
+ const isValidArr = conditionCrowdloan.map(condition => {
258
+ return conditionMap[JSON.stringify(condition)];
259
+ });
260
+ isPassValidation.push(isValidArr.some(i => i));
261
+ }
262
+ if (conditionHasMoney && conditionHasMoney.length) {
263
+ const isValidArr = conditionHasMoney.map(condition => {
264
+ return conditionMap[JSON.stringify(condition)];
265
+ });
266
+ isPassValidation.push(isValidArr.some(i => i));
267
+ }
268
+ }
269
+ if (isPassValidation && isPassValidation.length) {
270
+ return isPassValidation.some(_i => _i);
271
+ } else {
272
+ return true;
273
+ }
274
+ }
275
+ }
@@ -0,0 +1,107 @@
1
+ export declare type PopupFrequency = 'once' | 'daily' | 'weekly' | 'monthly' | 'every_time' | null;
2
+ export declare type OnlineContentDataType = 'popup' | 'banner' | 'confirmation';
3
+ export interface PopupHistoryData {
4
+ lastShowTime: number;
5
+ showTimes: number;
6
+ }
7
+ export interface AppBasicInfoData {
8
+ id: number;
9
+ name: string;
10
+ description: string | null;
11
+ start_time: string;
12
+ stop_time: string;
13
+ platforms: string[];
14
+ os: 'android' | 'ios';
15
+ is_changelog_popup?: boolean;
16
+ }
17
+ export interface AppContentButtonInstruction {
18
+ id: number;
19
+ confirm_label: string;
20
+ cancel_label: string;
21
+ instruction_id: number;
22
+ group: string;
23
+ slug: string;
24
+ }
25
+ export interface AppContentButtonAction {
26
+ id: number;
27
+ url: string;
28
+ screen: string;
29
+ params: string | null;
30
+ is_cancel: boolean;
31
+ }
32
+ export interface AppContentButton {
33
+ id: number;
34
+ label: string;
35
+ color: 'primary' | 'secondary' | 'warning' | 'danger' | 'ghost';
36
+ instruction: AppContentButtonInstruction | null;
37
+ action: AppContentButtonAction | null;
38
+ }
39
+ export declare type ComparisonMethod = 'eq' | 'gt' | 'gte' | 'lt' | 'lte';
40
+ export declare type ConditionBalanceType = {
41
+ comparison: ComparisonMethod;
42
+ value: number;
43
+ chain_asset: string;
44
+ };
45
+ export declare type ConditionEarningType = {
46
+ comparison: ComparisonMethod;
47
+ value: number;
48
+ pool_slug: string;
49
+ };
50
+ export declare type ConditionNftType = {
51
+ chain: string;
52
+ collection_id: string;
53
+ };
54
+ export declare type ConditionCrowdloanType = {
55
+ chain: string;
56
+ };
57
+ export declare type ConditionHasMoneyType = {
58
+ has_money: string[];
59
+ };
60
+ export declare type ConditionType = 'condition-balance' | 'condition-earning' | 'condition-nft' | 'condition-crowdloan' | 'condition-has-money';
61
+ export declare enum MktCampaignConditionTypeValue {
62
+ BALANCE = "condition-balance",
63
+ EARNING = "condition-earning",
64
+ NFT = "condition-nft",
65
+ CROWDLOAN = "condition-crowdloan",
66
+ HAS_MONEY = "condition-has-money"
67
+ }
68
+ export interface MktCampaignCondition {
69
+ [MktCampaignConditionTypeValue.BALANCE]: ConditionBalanceType[];
70
+ [MktCampaignConditionTypeValue.EARNING]: ConditionEarningType[];
71
+ [MktCampaignConditionTypeValue.NFT]: ConditionNftType[];
72
+ [MktCampaignConditionTypeValue.CROWDLOAN]: ConditionCrowdloanType[];
73
+ [MktCampaignConditionTypeValue.HAS_MONEY]: ConditionHasMoneyType[];
74
+ }
75
+ export interface PositionParam {
76
+ property: string;
77
+ value: string;
78
+ }
79
+ export interface AppCommonData {
80
+ id: number;
81
+ position: string;
82
+ position_params: PositionParam[];
83
+ conditions: MktCampaignCondition;
84
+ info?: AppBasicInfoData;
85
+ }
86
+ export interface AppPopupData extends AppCommonData {
87
+ priority: number;
88
+ repeat: PopupFrequency;
89
+ content: string;
90
+ media: string;
91
+ buttons: AppContentButton[];
92
+ repeat_every_x_days: number | null;
93
+ }
94
+ export interface AppBannerData extends AppCommonData {
95
+ priority: number;
96
+ media: string;
97
+ action: AppContentButtonAction;
98
+ instruction: AppContentButtonInstruction | null;
99
+ }
100
+ export interface AppConfirmationData extends AppCommonData {
101
+ name: string;
102
+ repeat: PopupFrequency;
103
+ confirm_label: string;
104
+ cancel_label: string;
105
+ content: string;
106
+ repeat_every_x_days: number | null;
107
+ }
@@ -0,0 +1,11 @@
1
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export let MktCampaignConditionTypeValue;
5
+ (function (MktCampaignConditionTypeValue) {
6
+ MktCampaignConditionTypeValue["BALANCE"] = "condition-balance";
7
+ MktCampaignConditionTypeValue["EARNING"] = "condition-earning";
8
+ MktCampaignConditionTypeValue["NFT"] = "condition-nft";
9
+ MktCampaignConditionTypeValue["CROWDLOAN"] = "condition-crowdloan";
10
+ MktCampaignConditionTypeValue["HAS_MONEY"] = "condition-has-money";
11
+ })(MktCampaignConditionTypeValue || (MktCampaignConditionTypeValue = {}));
@@ -44,6 +44,11 @@ export default class DatabaseService {
44
44
  updatePriceStore(priceData: PriceJson): Promise<void>;
45
45
  getPriceStore(keyData?: string): Promise<PriceJson | undefined>;
46
46
  getStoredBalance(): Promise<IBalance[]>;
47
+ checkBalanceByTokens(tokens: string[], comparison: 'eq' | 'gt' | 'gte' | 'lt' | 'lte', addresses: string[], amount: string): Promise<number>;
48
+ checkEarningByTokens(slug: string, comparison: 'eq' | 'gt' | 'gte' | 'lt' | 'lte', addresses: string[], amount: string): Promise<number>;
49
+ checkNftByTokens(chain: string, addresses: string[], collectionId?: string): Promise<number>;
50
+ checkCrowdloanByChain(chain: string, addresses: string[]): Promise<number>;
51
+ checkHasMoneyByTokens(types: string[], addresses: string[]): Promise<number>;
47
52
  updateBalanceStore(item: BalanceItem): Promise<unknown>;
48
53
  updateBulkBalanceStore(items: BalanceItem[]): Promise<unknown>;
49
54
  removeFromBalanceStore(assets: string[]): Promise<number>;
@@ -10,8 +10,9 @@ import MantaPayStore from '@subwallet/extension-base/services/storage-service/db
10
10
  import NominatorMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata';
11
11
  import YieldPoolStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore';
12
12
  import YieldPositionStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPositionStore';
13
- import { reformatAddress } from '@subwallet/extension-base/utils';
13
+ import { BN_ZERO, reformatAddress } from '@subwallet/extension-base/utils';
14
14
  import keyring from '@subwallet/ui-keyring';
15
+ import BigN from 'bignumber.js';
15
16
  import { exportDB } from 'dexie-export-import';
16
17
  import { logger as createLogger } from '@polkadot/util';
17
18
  export const DEXIE_BACKUP_TABLES = ['chain', 'asset', 'migrations', 'transactions', 'campaign'];
@@ -70,6 +71,120 @@ export default class DatabaseService {
70
71
  // Filter not exist address
71
72
  return this.stores.balance.table.filter(obj => addresses.includes(obj.address)).toArray();
72
73
  }
74
+ async checkBalanceByTokens(tokens, comparison, addresses, amount) {
75
+ const filterFunc = item => {
76
+ const freeBalance = item === null || item === void 0 ? void 0 : item.free;
77
+ const lockedBalance = item === null || item === void 0 ? void 0 : item.locked;
78
+ const value = new BigN(freeBalance).plus(lockedBalance);
79
+ if (!addresses.includes(item.address)) {
80
+ return false;
81
+ }
82
+ switch (comparison) {
83
+ case 'eq':
84
+ return value.eq(amount || 0);
85
+ case 'gt':
86
+ return value.gt(amount || 0);
87
+ case 'gte':
88
+ return value.gte(amount || 0);
89
+ case 'lt':
90
+ return value.lt(amount || 0);
91
+ case 'lte':
92
+ return value.lte(amount || 0);
93
+ }
94
+ };
95
+ return this.stores.balance.checkBalanceByTokens(tokens, filterFunc);
96
+ }
97
+ async checkEarningByTokens(slug, comparison, addresses, amount) {
98
+ const filterFunc = item => {
99
+ if (!addresses.includes(item.address)) {
100
+ return false;
101
+ }
102
+ const value = new BigN(item.activeStake);
103
+ switch (comparison) {
104
+ case 'eq':
105
+ return value.eq(amount || 0);
106
+ case 'gt':
107
+ return value.gt(amount || 0);
108
+ case 'gte':
109
+ return value.gte(amount || 0);
110
+ case 'lt':
111
+ return value.lt(amount || 0);
112
+ case 'lte':
113
+ return value.lte(amount || 0);
114
+ }
115
+ };
116
+ return this.stores.yieldPosition.checkPositionByPoolSlug(slug, filterFunc);
117
+ }
118
+ async checkNftByTokens(chain, addresses, collectionId) {
119
+ const filterFunc = item => {
120
+ if (!addresses.includes(item.address)) {
121
+ return false;
122
+ } else {
123
+ return true;
124
+ }
125
+ };
126
+ return this.stores.nft.checkNftsByChainAndCollection(chain, filterFunc, collectionId);
127
+ }
128
+ async checkCrowdloanByChain(chain, addresses) {
129
+ const filterFunc = item => {
130
+ if (!addresses.includes(item.address)) {
131
+ return false;
132
+ } else {
133
+ return true;
134
+ }
135
+ };
136
+ return this.stores.crowdloan.checkCrowdloanExist(filterFunc);
137
+ }
138
+ async checkHasMoneyByTokens(types, addresses) {
139
+ const allHasMoneysConditionValid = [];
140
+ if (types.includes('balance')) {
141
+ const filterFunc = item => {
142
+ if (!addresses.includes(item.address)) {
143
+ return false;
144
+ }
145
+ const freeBalance = item === null || item === void 0 ? void 0 : item.free;
146
+ const lockedBalance = item === null || item === void 0 ? void 0 : item.locked;
147
+ const value = new BigN(freeBalance).plus(lockedBalance);
148
+ return value.gt(BN_ZERO);
149
+ };
150
+ const balanceResult = await this.stores.balance.checkBalanceExist(filterFunc);
151
+ balanceResult > 0 && allHasMoneysConditionValid.push('balance');
152
+ }
153
+ if (types.includes('earning')) {
154
+ const filterFunc = item => {
155
+ if (!addresses.includes(item.address)) {
156
+ return false;
157
+ }
158
+ const value = new BigN(item.activeStake);
159
+ return value.gt(BN_ZERO);
160
+ };
161
+ const earningResult = await this.stores.yieldPosition.checkPositionExist(filterFunc);
162
+ earningResult > 0 && allHasMoneysConditionValid.push('earning');
163
+ }
164
+ if (types.includes('nft')) {
165
+ const filterFunc = item => {
166
+ if (!addresses.includes(item.address)) {
167
+ return false;
168
+ } else {
169
+ return true;
170
+ }
171
+ };
172
+ const nftResult = await this.stores.nft.checkNftExist(filterFunc);
173
+ nftResult > 0 && allHasMoneysConditionValid.push('nft');
174
+ }
175
+ if (types.includes('crowdloan')) {
176
+ const filterFunc = item => {
177
+ if (!addresses.includes(item.address)) {
178
+ return false;
179
+ } else {
180
+ return true;
181
+ }
182
+ };
183
+ const crowdloanResult = await this.stores.crowdloan.checkCrowdloanExist(filterFunc);
184
+ crowdloanResult > 0 && allHasMoneysConditionValid.push('crowdloan');
185
+ }
186
+ return allHasMoneysConditionValid.length;
187
+ }
73
188
  async updateBalanceStore(item) {
74
189
  if (item.state === APIItemState.READY) {
75
190
  return this.stores.balance.upsert({
@@ -5,4 +5,6 @@ export default class BalanceStore extends BaseStoreWithAddress<IBalance> {
5
5
  getBalanceMapByAddresses(addresses: string): Promise<BalanceItem[]>;
6
6
  removeBySlugs(tokenSlugs: string[]): Promise<number>;
7
7
  removeByAddresses(addresses: string[]): Promise<number>;
8
+ checkBalanceByTokens(tokens: string[], filterFunc: (i: IBalance) => boolean): Promise<number>;
9
+ checkBalanceExist(filterFunc: (x: IBalance) => boolean): Promise<number>;
8
10
  }
@@ -12,4 +12,10 @@ export default class BalanceStore extends BaseStoreWithAddress {
12
12
  async removeByAddresses(addresses) {
13
13
  return this.table.where('address').anyOfIgnoreCase(addresses).delete();
14
14
  }
15
+ async checkBalanceByTokens(tokens, filterFunc) {
16
+ return this.table.where('tokenSlug').anyOfIgnoreCase(tokens).filter(filterFunc).count();
17
+ }
18
+ async checkBalanceExist(filterFunc) {
19
+ return this.table.filter(item => filterFunc(item)).count();
20
+ }
15
21
  }
@@ -4,4 +4,6 @@ export default class CrowdloanStore extends BaseStoreWithAddressAndChain<ICrowdl
4
4
  removeEndedCrowdloans(): Promise<void>;
5
5
  getCrowdloan(address: string): import("dexie").PromiseExtended<ICrowdloanItem[]>;
6
6
  deleteByChainAndAddress(chain: string, address: string): import("dexie").PromiseExtended<number>;
7
+ checkCrowdloanByChain(chain: string, filterFunc: (i: ICrowdloanItem) => boolean): import("dexie").PromiseExtended<number>;
8
+ checkCrowdloanExist(filterFunc: (i: ICrowdloanItem) => boolean): import("dexie").PromiseExtended<number>;
7
9
  }
@@ -26,4 +26,12 @@ export default class CrowdloanStore extends BaseStoreWithAddressAndChain {
26
26
  address
27
27
  }).delete();
28
28
  }
29
+ checkCrowdloanByChain(chain, filterFunc) {
30
+ return this.table.where({
31
+ chain
32
+ }).filter(filterFunc).count();
33
+ }
34
+ checkCrowdloanExist(filterFunc) {
35
+ return this.table.filter(filterFunc).count();
36
+ }
29
37
  }
@@ -11,4 +11,6 @@ export default class NftStore extends BaseStoreWithAddressAndChain<INft> {
11
11
  deleteNftsByCollection(chain: string, collectionId: string): import("dexie").PromiseExtended<number>;
12
12
  removeNfts(chain: string, address: string, collectionId: string, nftIds: string[]): import("dexie").PromiseExtended<number>;
13
13
  removeNftsByAddress(addresses: string[]): import("dexie").PromiseExtended<number>;
14
+ checkNftsByChainAndCollection(chain: string, filterFunc: (x: INft) => boolean, collectionId?: string): import("dexie").PromiseExtended<number>;
15
+ checkNftExist(filterFunc: (x: INft) => boolean): import("dexie").PromiseExtended<number>;
14
16
  }
@@ -49,6 +49,18 @@ export default class NftStore extends BaseStoreWithAddressAndChain {
49
49
  removeNftsByAddress(addresses) {
50
50
  return this.table.where('address').anyOfIgnoreCase(addresses).delete();
51
51
  }
52
+ checkNftsByChainAndCollection(chain, filterFunc, collectionId) {
53
+ const data = collectionId ? this.table.where({
54
+ chain,
55
+ collectionId
56
+ }) : this.table.where({
57
+ chain
58
+ });
59
+ return data.filter(item => filterFunc(item)).count();
60
+ }
61
+ checkNftExist(filterFunc) {
62
+ return this.table.filter(filterFunc).count();
63
+ }
52
64
 
53
65
  // reformatCollectionIds (items: INft[]) {
54
66
  // return items.map((item) => {
@@ -4,4 +4,5 @@ export default class NftCollectionStore extends BaseStoreWithChain<NftCollection
4
4
  subscribeNftCollection(getChains: () => string[] | undefined): import("dexie").Observable<NftCollection[]>;
5
5
  getNftCollection(chainList?: string[]): import("dexie").PromiseExtended<NftCollection[]>;
6
6
  removeCollection(chain: string, collectionId: string): import("dexie").PromiseExtended<number>;
7
+ checkNftByChainOrCollectionId(chain: string, collectionId?: string): Promise<number>;
7
8
  }
@@ -19,4 +19,15 @@ export default class NftCollectionStore extends BaseStoreWithChain {
19
19
  collectionId
20
20
  }).delete();
21
21
  }
22
+ async checkNftByChainOrCollectionId(chain, collectionId) {
23
+ if (collectionId) {
24
+ return this.table.where({
25
+ chain,
26
+ collectionId
27
+ }).count();
28
+ }
29
+ return this.table.where({
30
+ chain
31
+ }).count();
32
+ }
22
33
  }
@@ -8,4 +8,6 @@ export default class YieldPositionStore extends BaseStore<YieldPositionInfo> {
8
8
  getByAddressAndChains(addresses: string[], chains: string[]): Promise<YieldPositionInfo[]>;
9
9
  getByAddressAndSlug(address: string, slug: string): import("dexie").PromiseExtended<YieldPositionInfo | undefined>;
10
10
  subscribeYieldPositions(addresses: string[]): import("dexie").Observable<YieldPositionInfo[]>;
11
+ checkPositionByPoolSlug(slug: string, filterFunc: (i: YieldPositionInfo) => boolean): Promise<number>;
12
+ checkPositionExist(filterFunc: (i: YieldPositionInfo) => boolean): Promise<number>;
11
13
  }
@@ -60,4 +60,10 @@ export default class YieldPositionStore extends BaseStore {
60
60
  subscribeYieldPositions(addresses) {
61
61
  return liveQuery(() => this.getByAddress(addresses));
62
62
  }
63
+ async checkPositionByPoolSlug(slug, filterFunc) {
64
+ return this.table.where('slug').anyOfIgnoreCase(slug).filter(filterFunc).limit(1).count();
65
+ }
66
+ async checkPositionExist(filterFunc) {
67
+ return this.table.filter(filterFunc).limit(1).count();
68
+ }
63
69
  }
@@ -1,7 +1,6 @@
1
1
  import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { _BalanceMetadata, APIItemState, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
- import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
4
- import { ApiPromise } from '@polkadot/api';
3
+ import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
5
4
  import { BN } from '@polkadot/util';
6
5
  export interface TokenBalanceRaw {
7
6
  reserved: BN;
@@ -43,7 +42,7 @@ export interface SubscribeBasePalletBalance {
43
42
  extrinsicType?: ExtrinsicType;
44
43
  }
45
44
  export interface SubscribeSubstratePalletBalance extends SubscribeBasePalletBalance {
46
- substrateApi: ApiPromise;
45
+ substrateApi: _SubstrateApi;
47
46
  includeNativeToken?: boolean;
48
47
  }
49
48
  export interface SubscribeEvmPalletBalance extends SubscribeBasePalletBalance {