@subwallet/extension-base 1.3.3-0 → 1.3.5-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 (134) hide show
  1. package/background/KoniTypes.d.ts +14 -1
  2. package/background/KoniTypes.js +1 -0
  3. package/cjs/background/KoniTypes.js +1 -0
  4. package/cjs/constants/blocked-actions-list.js +1 -2
  5. package/cjs/constants/index.js +16 -1
  6. package/cjs/constants/remind-notification-time.js +14 -0
  7. package/cjs/core/logic-validation/transfer.js +12 -6
  8. package/cjs/core/substrate/xcm-parser.js +13 -1
  9. package/cjs/koni/api/contract-handler/utils/index.js +20 -1
  10. package/cjs/koni/api/nft/config.js +1 -1
  11. package/cjs/koni/api/nft/index.js +9 -0
  12. package/cjs/koni/api/nft/rari/index.js +87 -0
  13. package/cjs/koni/api/yield/helper/utils.js +1 -1
  14. package/cjs/koni/background/handlers/Extension.js +110 -23
  15. package/cjs/koni/background/handlers/State.js +5 -2
  16. package/cjs/packageInfo.js +1 -1
  17. package/cjs/services/balance-service/helpers/process.js +2 -1
  18. package/cjs/services/balance-service/helpers/subscribe/index.js +5 -0
  19. package/cjs/services/balance-service/index.js +1 -1
  20. package/cjs/services/balance-service/transfer/xcm/availBridge.js +198 -0
  21. package/cjs/services/balance-service/transfer/xcm/index.js +50 -5
  22. package/cjs/services/chain-service/constants.js +2 -1
  23. package/cjs/services/chain-service/handler/EvmApi.js +12 -21
  24. package/cjs/services/chain-service/handler/EvmChainHandler.js +0 -2
  25. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +73 -40
  26. package/cjs/services/chain-service/index.js +44 -13
  27. package/cjs/services/chain-service/utils/index.js +20 -0
  28. package/cjs/services/earning-service/handlers/base.js +12 -3
  29. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +11 -3
  30. package/cjs/services/earning-service/handlers/native-staking/astar.js +1 -1
  31. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +3 -1
  32. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +3 -1
  33. package/cjs/services/earning-service/handlers/native-staking/tao.js +11 -3
  34. package/cjs/services/earning-service/handlers/nomination-pool/index.js +14 -12
  35. package/cjs/services/earning-service/service.js +5 -0
  36. package/cjs/services/inapp-notification-service/consts.js +31 -0
  37. package/cjs/services/inapp-notification-service/index.js +260 -0
  38. package/cjs/services/inapp-notification-service/interfaces.js +32 -0
  39. package/cjs/services/inapp-notification-service/utils.js +197 -0
  40. package/cjs/services/keyring-service/context/account-context.js +9 -0
  41. package/cjs/services/keyring-service/context/state.js +4 -0
  42. package/cjs/services/setting-service/SettingService.js +9 -1
  43. package/cjs/services/setting-service/constants.js +16 -1
  44. package/cjs/services/storage-service/DatabaseService.js +42 -3
  45. package/cjs/services/storage-service/databases/index.js +3 -0
  46. package/cjs/services/storage-service/db-stores/InappNotification.js +81 -0
  47. package/cjs/services/transaction-service/index.js +18 -4
  48. package/cjs/types/avail-bridge/index.js +1 -0
  49. package/cjs/types/notification/index.js +1 -0
  50. package/cjs/utils/account/transform.js +9 -5
  51. package/cjs/utils/staticData/index.js +7 -2
  52. package/constants/blocked-actions-list.js +1 -2
  53. package/constants/index.d.ts +2 -0
  54. package/constants/index.js +3 -1
  55. package/constants/remind-notification-time.d.ts +2 -0
  56. package/constants/remind-notification-time.js +7 -0
  57. package/core/logic-validation/transfer.js +12 -6
  58. package/core/substrate/xcm-parser.d.ts +1 -0
  59. package/core/substrate/xcm-parser.js +12 -1
  60. package/koni/api/contract-handler/utils/avail_bridge_abi.json +1659 -0
  61. package/koni/api/contract-handler/utils/avail_test_bridge_abi.json +1692 -0
  62. package/koni/api/contract-handler/utils/index.d.ts +7 -2
  63. package/koni/api/contract-handler/utils/index.js +15 -0
  64. package/koni/api/nft/config.js +1 -1
  65. package/koni/api/nft/index.js +9 -0
  66. package/koni/api/nft/rari/index.d.ts +7 -0
  67. package/koni/api/nft/rari/index.js +80 -0
  68. package/koni/api/yield/helper/utils.js +1 -1
  69. package/koni/background/handlers/Extension.d.ts +7 -0
  70. package/koni/background/handlers/Extension.js +112 -25
  71. package/koni/background/handlers/State.d.ts +2 -0
  72. package/koni/background/handlers/State.js +5 -2
  73. package/package.json +59 -6
  74. package/packageInfo.js +1 -1
  75. package/services/balance-service/helpers/process.js +2 -1
  76. package/services/balance-service/helpers/subscribe/index.js +5 -0
  77. package/services/balance-service/index.js +2 -2
  78. package/services/balance-service/transfer/xcm/availBridge.d.ts +45 -0
  79. package/services/balance-service/transfer/xcm/availBridge.js +186 -0
  80. package/services/balance-service/transfer/xcm/index.d.ts +8 -8
  81. package/services/balance-service/transfer/xcm/index.js +46 -5
  82. package/services/chain-service/constants.d.ts +1 -0
  83. package/services/chain-service/constants.js +2 -1
  84. package/services/chain-service/handler/EvmApi.js +12 -21
  85. package/services/chain-service/handler/EvmChainHandler.js +0 -2
  86. package/services/chain-service/handler/SubstrateChainHandler.d.ts +3 -2
  87. package/services/chain-service/handler/SubstrateChainHandler.js +73 -40
  88. package/services/chain-service/index.d.ts +2 -0
  89. package/services/chain-service/index.js +45 -14
  90. package/services/chain-service/types.d.ts +2 -1
  91. package/services/chain-service/utils/index.d.ts +3 -0
  92. package/services/chain-service/utils/index.js +14 -0
  93. package/services/earning-service/handlers/base.d.ts +2 -0
  94. package/services/earning-service/handlers/base.js +9 -0
  95. package/services/earning-service/handlers/native-staking/amplitude.js +11 -3
  96. package/services/earning-service/handlers/native-staking/astar.js +1 -1
  97. package/services/earning-service/handlers/native-staking/para-chain.js +3 -1
  98. package/services/earning-service/handlers/native-staking/relay-chain.js +3 -1
  99. package/services/earning-service/handlers/native-staking/tao.d.ts +4 -0
  100. package/services/earning-service/handlers/native-staking/tao.js +6 -2
  101. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -1
  102. package/services/earning-service/handlers/nomination-pool/index.js +14 -12
  103. package/services/earning-service/service.d.ts +2 -0
  104. package/services/earning-service/service.js +5 -0
  105. package/services/inapp-notification-service/consts.d.ts +18 -0
  106. package/services/inapp-notification-service/consts.js +22 -0
  107. package/services/inapp-notification-service/index.d.ts +37 -0
  108. package/services/inapp-notification-service/index.js +252 -0
  109. package/services/inapp-notification-service/interfaces.d.ts +77 -0
  110. package/services/inapp-notification-service/interfaces.js +24 -0
  111. package/services/inapp-notification-service/utils.d.ts +55 -0
  112. package/services/inapp-notification-service/utils.js +173 -0
  113. package/services/keyring-service/context/account-context.d.ts +3 -0
  114. package/services/keyring-service/context/account-context.js +9 -0
  115. package/services/keyring-service/context/state.d.ts +1 -0
  116. package/services/keyring-service/context/state.js +4 -0
  117. package/services/setting-service/SettingService.js +9 -1
  118. package/services/setting-service/constants.d.ts +2 -0
  119. package/services/setting-service/constants.js +15 -0
  120. package/services/storage-service/DatabaseService.d.ts +15 -0
  121. package/services/storage-service/DatabaseService.js +42 -3
  122. package/services/storage-service/databases/index.d.ts +2 -0
  123. package/services/storage-service/databases/index.js +3 -0
  124. package/services/storage-service/db-stores/InappNotification.d.ts +14 -0
  125. package/services/storage-service/db-stores/InappNotification.js +73 -0
  126. package/services/transaction-service/index.js +18 -4
  127. package/types/avail-bridge/index.d.ts +6 -0
  128. package/types/avail-bridge/index.js +1 -0
  129. package/types/notification/index.d.ts +9 -0
  130. package/types/notification/index.js +1 -0
  131. package/utils/account/transform.js +9 -5
  132. package/utils/staticData/index.d.ts +5 -1
  133. package/utils/staticData/index.js +5 -2
  134. package/utils/staticData/remindNotificationTime.json +1 -0
@@ -0,0 +1,252 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
5
+ import { CRON_LISTEN_AVAIL_BRIDGE_CLAIM } from '@subwallet/extension-base/constants';
6
+ import { fetchLastestRemindNotificationTime } from '@subwallet/extension-base/constants/remind-notification-time';
7
+ import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
8
+ import { NotificationDescriptionMap, NotificationTitleMap, ONE_DAY_MILLISECOND } from '@subwallet/extension-base/services/inapp-notification-service/consts';
9
+ import { NotificationActionType, NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
10
+ import { AvailBridgeSourceChain, fetchAllAvailBridgeClaimable, hrsToMillisecond } from '@subwallet/extension-base/services/inapp-notification-service/utils';
11
+ import { categoryAddresses, formatNumber } from '@subwallet/extension-base/utils';
12
+ import { isSubstrateAddress } from '@subwallet/keyring';
13
+ export class InappNotificationService {
14
+ constructor(dbService, keyringService, eventService, chainService) {
15
+ this.dbService = dbService;
16
+ this.keyringService = keyringService;
17
+ this.eventService = eventService;
18
+ this.chainService = chainService;
19
+ this.status = ServiceStatus.NOT_INITIALIZED;
20
+ }
21
+ async init() {
22
+ this.status = ServiceStatus.INITIALIZING;
23
+ await this.eventService.waitAccountReady;
24
+ this.status = ServiceStatus.INITIALIZED;
25
+ await this.start();
26
+ this.onAccountProxyRemove();
27
+ }
28
+ async markAllRead(proxyId) {
29
+ await this.dbService.markAllRead(proxyId);
30
+ }
31
+ async switchReadStatus(params) {
32
+ await this.dbService.switchReadStatus(params);
33
+ }
34
+ subscribeUnreadNotificationsCountMap(callback) {
35
+ return this.dbService.subscribeUnreadNotificationsCountMap().subscribe({
36
+ next: callback
37
+ });
38
+ }
39
+ async getUnreadNotificationsCountMap() {
40
+ return await this.dbService.getUnreadNotificationsCountMap();
41
+ }
42
+ async fetchNotificationsByParams(params) {
43
+ return this.dbService.getNotificationsByParams(params);
44
+ }
45
+ async getNotificationById(id) {
46
+ return this.dbService.getNotification(id);
47
+ }
48
+ cleanUpOldNotifications(overdueTime = ONE_DAY_MILLISECOND * 60) {
49
+ return this.dbService.cleanUpOldNotifications(overdueTime);
50
+ }
51
+ passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfigInHrs) {
52
+ // todo: simplify condition !!
53
+ if ([NotificationActionType.WITHDRAW, NotificationActionType.CLAIM].includes(candidateNotification.actionType)) {
54
+ const {
55
+ actionType,
56
+ address,
57
+ metadata,
58
+ time
59
+ } = candidateNotification;
60
+ const candidateMetadata = metadata;
61
+ const remindTime = hrsToMillisecond(remindTimeConfigInHrs[candidateNotification.actionType]);
62
+ for (const comparedNotification of comparedNotifications) {
63
+ const specialCase = comparedNotification.actionType === NotificationActionType.WITHDRAW && !comparedNotification.isRead;
64
+ if (comparedNotification.address !== address) {
65
+ continue;
66
+ }
67
+ if (comparedNotification.actionType !== actionType) {
68
+ continue;
69
+ }
70
+ const comparedMetadata = comparedNotification.metadata;
71
+ const sameNotification = candidateMetadata.stakingType === comparedMetadata.stakingType && candidateMetadata.stakingSlug === comparedMetadata.stakingSlug;
72
+ if (!sameNotification) {
73
+ continue;
74
+ }
75
+ if (time - comparedNotification.time <= remindTime) {
76
+ return false;
77
+ } else {
78
+ if (specialCase) {
79
+ return false;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ if ([NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM, NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL].includes(candidateNotification.actionType)) {
85
+ const {
86
+ address,
87
+ metadata,
88
+ time
89
+ } = candidateNotification;
90
+ const candidateMetadata = metadata;
91
+ const remindTime = hrsToMillisecond(remindTimeConfigInHrs[candidateNotification.actionType]);
92
+ for (const notification of comparedNotifications) {
93
+ if (notification.address !== address) {
94
+ continue;
95
+ }
96
+ if (time - notification.time >= remindTime) {
97
+ continue;
98
+ }
99
+ const comparedMetadata = notification.metadata;
100
+ const sameNotification = candidateMetadata.messageId === comparedMetadata.messageId && candidateMetadata.sourceBlockHash === comparedMetadata.sourceBlockHash && candidateMetadata.sourceTransactionHash === comparedMetadata.sourceTransactionHash;
101
+ if (sameNotification) {
102
+ return false;
103
+ }
104
+ }
105
+ }
106
+ return true;
107
+ }
108
+ async validateAndWriteNotificationsToDB(notifications, address) {
109
+ const proxyId = this.keyringService.context.belongUnifiedAccount(address) || address;
110
+ const accountName = this.keyringService.context.getCurrentAccountProxyName(proxyId);
111
+ const passNotifications = [];
112
+ const [comparedNotifications, remindTimeConfig] = await Promise.all([this.fetchNotificationsByParams({
113
+ notificationTab: NotificationTab.ALL,
114
+ proxyId
115
+ }), await fetchLastestRemindNotificationTime()]);
116
+ for (const candidateNotification of notifications) {
117
+ candidateNotification.title = candidateNotification.title.replace('{{accountName}}', accountName);
118
+ if (this.passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfig)) {
119
+ passNotifications.push({
120
+ ...candidateNotification,
121
+ proxyId
122
+ });
123
+ }
124
+ }
125
+ await this.dbService.upsertNotifications(passNotifications);
126
+ }
127
+ cronCreateAvailBridgeClaimNotification() {
128
+ clearTimeout(this.refeshAvailBridgeClaimTimeOut);
129
+ this.createAvailBridgeClaimNotification();
130
+ this.refeshAvailBridgeClaimTimeOut = setTimeout(this.cronCreateAvailBridgeClaimNotification.bind(this), CRON_LISTEN_AVAIL_BRIDGE_CLAIM);
131
+ }
132
+ createAvailBridgeClaimNotification() {
133
+ const addresses = this.keyringService.context.getAllAddresses();
134
+ const {
135
+ evm: evmAddresses,
136
+ substrate: substrateAddresses
137
+ } = categoryAddresses(addresses);
138
+ const chainAssets = this.chainService.getAssetRegistry();
139
+ let ASSET_TYPE;
140
+ (function (ASSET_TYPE) {
141
+ ASSET_TYPE["TEST_EVM"] = "test_evm";
142
+ ASSET_TYPE["TEST_SUBSTRATE"] = "test_substrate";
143
+ ASSET_TYPE["MAIN_EVM"] = "main_evm";
144
+ ASSET_TYPE["MAIN_SUBSTRATE"] = "main_substrate";
145
+ })(ASSET_TYPE || (ASSET_TYPE = {}));
146
+ const chainAssetMap = Object.values(chainAssets).reduce((acc, chainAsset) => {
147
+ let type;
148
+ if (chainAsset.symbol === 'AVAIL') {
149
+ if (chainAsset.originChain === 'sepolia_ethereum') {
150
+ type = ASSET_TYPE.TEST_EVM;
151
+ } else if (chainAsset.originChain === 'availTuringTest') {
152
+ type = ASSET_TYPE.TEST_SUBSTRATE;
153
+ } else if (chainAsset.originChain === 'ethereum') {
154
+ type = ASSET_TYPE.MAIN_EVM;
155
+ } else if (chainAsset.originChain === 'avail_mainnet') {
156
+ type = ASSET_TYPE.MAIN_SUBSTRATE;
157
+ }
158
+ }
159
+ if (type) {
160
+ acc[type] = chainAsset;
161
+ }
162
+ return acc;
163
+ }, {});
164
+ substrateAddresses.forEach(address => {
165
+ fetchAllAvailBridgeClaimable(address, AvailBridgeSourceChain.ETHEREUM, true).then(async transactions => await this.processWriteAvailBridgeClaim(address, transactions, chainAssetMap[ASSET_TYPE.TEST_SUBSTRATE])).catch(console.error);
166
+ fetchAllAvailBridgeClaimable(address, AvailBridgeSourceChain.ETHEREUM, false).then(async transactions => await this.processWriteAvailBridgeClaim(address, transactions, chainAssetMap[ASSET_TYPE.MAIN_SUBSTRATE])).catch(console.error);
167
+ });
168
+ evmAddresses.forEach(address => {
169
+ fetchAllAvailBridgeClaimable(address, AvailBridgeSourceChain.AVAIL, true).then(async transactions => await this.processWriteAvailBridgeClaim(address, transactions, chainAssetMap[ASSET_TYPE.TEST_EVM])).catch(console.error);
170
+ fetchAllAvailBridgeClaimable(address, AvailBridgeSourceChain.AVAIL, false).then(async transactions => await this.processWriteAvailBridgeClaim(address, transactions, chainAssetMap[ASSET_TYPE.MAIN_EVM])).catch(console.error);
171
+ });
172
+ }
173
+ async processWriteAvailBridgeClaim(address, transactions, token) {
174
+ var _token$decimals;
175
+ const actionType = isSubstrateAddress(address) ? NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL : NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM;
176
+ const timestamp = Date.now();
177
+ const symbol = token.symbol;
178
+ const decimals = (_token$decimals = token.decimals) !== null && _token$decimals !== void 0 ? _token$decimals : 0;
179
+ const notifications = transactions.map(transaction => {
180
+ const {
181
+ amount,
182
+ depositorAddress,
183
+ messageId,
184
+ receiverAddress,
185
+ sourceBlockHash,
186
+ sourceChain,
187
+ sourceTransactionHash,
188
+ sourceTransactionIndex,
189
+ status
190
+ } = transaction;
191
+ const metadata = {
192
+ chainSlug: token.originChain,
193
+ tokenSlug: token.slug,
194
+ messageId,
195
+ sourceChain,
196
+ sourceTransactionHash,
197
+ depositorAddress,
198
+ receiverAddress,
199
+ amount,
200
+ sourceBlockHash,
201
+ sourceTransactionIndex,
202
+ status
203
+ };
204
+ return {
205
+ id: `${actionType}___${messageId}___${timestamp}`,
206
+ address: address,
207
+ // address is receiverAddress
208
+ title: NotificationTitleMap[actionType].replace('{{tokenSymbol}}', symbol),
209
+ description: NotificationDescriptionMap[actionType](formatNumber(amount, decimals), symbol),
210
+ time: timestamp,
211
+ extrinsicType: ExtrinsicType.CLAIM_AVAIL_BRIDGE,
212
+ isRead: false,
213
+ actionType,
214
+ metadata
215
+ };
216
+ });
217
+ await this.validateAndWriteNotificationsToDB(notifications, address);
218
+ }
219
+ async start() {
220
+ if (this.status === ServiceStatus.STARTED) {
221
+ return;
222
+ }
223
+ try {
224
+ this.status = ServiceStatus.STARTING;
225
+ await this.startCron();
226
+ this.status = ServiceStatus.STARTED;
227
+ } catch (e) {}
228
+ }
229
+ async startCron() {
230
+ this.cleanUpOldNotifications().catch(console.error);
231
+ this.cronCreateAvailBridgeClaimNotification();
232
+ return Promise.resolve();
233
+ }
234
+ async stop() {
235
+ try {
236
+ this.status = ServiceStatus.STOPPING;
237
+ await this.stopCron();
238
+ this.status = ServiceStatus.STOPPED;
239
+ } catch (e) {}
240
+ }
241
+ stopCron() {
242
+ return Promise.resolve(undefined);
243
+ }
244
+ onAccountProxyRemove() {
245
+ this.eventService.on('accountProxy.remove', proxyId => {
246
+ this.removeAccountNotifications(proxyId);
247
+ });
248
+ }
249
+ removeAccountNotifications(proxyId) {
250
+ this.dbService.removeAccountNotifications(proxyId).catch(console.error);
251
+ }
252
+ }
@@ -0,0 +1,77 @@
1
+ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { AvailBridgeSourceChain, AvailBridgeTransactionStatus } from '@subwallet/extension-base/services/inapp-notification-service/utils';
3
+ import { YieldPoolType } from '@subwallet/extension-base/types';
4
+ export interface _BaseNotificationInfo {
5
+ id: string;
6
+ title: string;
7
+ description: string;
8
+ address: string;
9
+ time: number;
10
+ extrinsicType: ExtrinsicType;
11
+ isRead: boolean;
12
+ actionType: NotificationActionType;
13
+ metadata: ActionTypeToMetadataMap[NotificationActionType];
14
+ }
15
+ export interface _NotificationInfo extends _BaseNotificationInfo {
16
+ proxyId: string;
17
+ }
18
+ export interface ActionTypeToMetadataMap {
19
+ [NotificationActionType.SEND]: SendReceiveNotificationMetadata;
20
+ [NotificationActionType.RECEIVE]: SendReceiveNotificationMetadata;
21
+ [NotificationActionType.WITHDRAW]: WithdrawClaimNotificationMetadata;
22
+ [NotificationActionType.CLAIM]: WithdrawClaimNotificationMetadata;
23
+ [NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL]: ClaimAvailBridgeNotificationMetadata;
24
+ [NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM]: ClaimAvailBridgeNotificationMetadata;
25
+ }
26
+ export interface SendReceiveNotificationMetadata {
27
+ chain: string;
28
+ from: string;
29
+ to: string;
30
+ extrinsicHash: string;
31
+ amount: bigint;
32
+ tokenSlug: string;
33
+ }
34
+ export interface WithdrawClaimNotificationMetadata {
35
+ stakingType: YieldPoolType;
36
+ stakingSlug: string;
37
+ }
38
+ export interface ClaimAvailBridgeNotificationMetadata {
39
+ chainSlug: string;
40
+ tokenSlug: string;
41
+ messageId: string;
42
+ sourceChain: AvailBridgeSourceChain;
43
+ sourceTransactionHash: string;
44
+ depositorAddress: string;
45
+ receiverAddress: string;
46
+ amount: string;
47
+ sourceBlockHash: string;
48
+ sourceTransactionIndex: string;
49
+ status: AvailBridgeTransactionStatus;
50
+ }
51
+ export declare enum NotificationTimePeriod {
52
+ TODAY = "TODAY",
53
+ THIS_WEEK = "THIS_WEEK",
54
+ THIS_MONTH = "THIS_MONTH"
55
+ }
56
+ export declare enum NotificationActionType {
57
+ SEND = "SEND",
58
+ RECEIVE = "RECEIVE",
59
+ WITHDRAW = "WITHDRAW",
60
+ CLAIM = "CLAIM",
61
+ CLAIM_AVAIL_BRIDGE_ON_AVAIL = "CLAIM_AVAIL_BRIDGE_ON_AVAIL",
62
+ CLAIM_AVAIL_BRIDGE_ON_ETHEREUM = "CLAIM_AVAIL_BRIDGE_ON_ETHEREUM"
63
+ }
64
+ export declare enum NotificationTab {
65
+ ALL = "ALL",
66
+ UNREAD = "UNREAD",
67
+ READ = "READ"
68
+ }
69
+ export interface ShowNotificationPayload {
70
+ earningClaim: boolean;
71
+ earningWithdraw: boolean;
72
+ availBridgeClaim: boolean;
73
+ }
74
+ export interface NotificationSetup {
75
+ isEnabled: boolean;
76
+ showNotice: ShowNotificationPayload;
77
+ }
@@ -0,0 +1,24 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export let NotificationTimePeriod;
5
+ (function (NotificationTimePeriod) {
6
+ NotificationTimePeriod["TODAY"] = "TODAY";
7
+ NotificationTimePeriod["THIS_WEEK"] = "THIS_WEEK";
8
+ NotificationTimePeriod["THIS_MONTH"] = "THIS_MONTH";
9
+ })(NotificationTimePeriod || (NotificationTimePeriod = {}));
10
+ export let NotificationActionType;
11
+ (function (NotificationActionType) {
12
+ NotificationActionType["SEND"] = "SEND";
13
+ NotificationActionType["RECEIVE"] = "RECEIVE";
14
+ NotificationActionType["WITHDRAW"] = "WITHDRAW";
15
+ NotificationActionType["CLAIM"] = "CLAIM";
16
+ NotificationActionType["CLAIM_AVAIL_BRIDGE_ON_AVAIL"] = "CLAIM_AVAIL_BRIDGE_ON_AVAIL";
17
+ NotificationActionType["CLAIM_AVAIL_BRIDGE_ON_ETHEREUM"] = "CLAIM_AVAIL_BRIDGE_ON_ETHEREUM";
18
+ })(NotificationActionType || (NotificationActionType = {}));
19
+ export let NotificationTab;
20
+ (function (NotificationTab) {
21
+ NotificationTab["ALL"] = "ALL";
22
+ NotificationTab["UNREAD"] = "UNREAD";
23
+ NotificationTab["READ"] = "READ";
24
+ })(NotificationTab || (NotificationTab = {}));
@@ -0,0 +1,55 @@
1
+ import { _ChainAsset } from '@subwallet/chain-list/types';
2
+ import { _BaseNotificationInfo, NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
3
+ import { EarningRewardItem, UnstakingInfo, YieldPoolType } from '@subwallet/extension-base/types';
4
+ export declare function getWithdrawDescription(amount: string, symbol: string, stakingType: YieldPoolType): string;
5
+ export declare function getClaimDescription(amount: string, symbol: string): string;
6
+ export declare function getSendDescription(amount: string, symbol: string): string;
7
+ export declare function getReceiveDescription(amount: string, symbol: string): string;
8
+ export declare function getAvailBridgeClaimDescription(amount: string, symbol: string): string;
9
+ export declare function getIsTabRead(notificationTab: NotificationTab): boolean | undefined;
10
+ export declare function createWithdrawNotifications(unstakingInfos: UnstakingInfo[], tokenInfo: _ChainAsset, address: string, stakingSlug: string, stakingType: YieldPoolType): _BaseNotificationInfo[];
11
+ export declare function createClaimNotification(claimItemInfo: EarningRewardItem, tokenInfo: _ChainAsset): _BaseNotificationInfo;
12
+ export declare const AVAIL_BRIDGE_INDEXER: {
13
+ AVAIL_MAINNET: string;
14
+ AVAIL_TESTNET: string;
15
+ };
16
+ export declare const AVAIL_BRIDGE_API: {
17
+ AVAIL_MAINNET: string;
18
+ AVAIL_TESTNET: string;
19
+ };
20
+ interface AvailBridgeTransactionsResponse {
21
+ data: {
22
+ paginationData: {
23
+ hasNextPage: boolean;
24
+ page: number;
25
+ pageSize: number;
26
+ totalCount: number;
27
+ };
28
+ result: AvailBridgeTransaction[];
29
+ };
30
+ }
31
+ export interface AvailBridgeTransaction {
32
+ messageId: string;
33
+ sourceChain: AvailBridgeSourceChain;
34
+ sourceTransactionHash: string;
35
+ depositorAddress: string;
36
+ receiverAddress: string;
37
+ amount: string;
38
+ sourceBlockHash: string;
39
+ sourceTransactionIndex: string;
40
+ status: AvailBridgeTransactionStatus;
41
+ }
42
+ export declare enum AvailBridgeTransactionStatus {
43
+ READY_TO_CLAIM = "READY_TO_CLAIM",
44
+ CLAIMED = "CLAIMED",
45
+ BRIDGED = "BRIDGED"
46
+ }
47
+ export declare enum AvailBridgeSourceChain {
48
+ AVAIL = "AVAIL",
49
+ ETHEREUM = "ETHEREUM"
50
+ }
51
+ export declare function fetchAllAvailBridgeClaimable(address: string, sourceChain: AvailBridgeSourceChain, isTestnet: boolean): Promise<AvailBridgeTransaction[]>;
52
+ export declare function fetchAvailBridgeTransactions(userAddress: string, sourceChain: AvailBridgeSourceChain, status: AvailBridgeTransactionStatus, pageSize: number | undefined, page: number | undefined, isTestnet: boolean): Promise<AvailBridgeTransactionsResponse | undefined>;
53
+ export declare function filterClaimableOfAddress(address: string, transactions: AvailBridgeTransaction[]): AvailBridgeTransaction[];
54
+ export declare function hrsToMillisecond(hours: number): number;
55
+ export {};
@@ -0,0 +1,173 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
5
+ import { _getAssetDecimals, _getAssetSymbol } from '@subwallet/extension-base/services/chain-service/utils';
6
+ import { NotificationDescriptionMap, NotificationTitleMap } from '@subwallet/extension-base/services/inapp-notification-service/consts';
7
+ import { NotificationActionType, NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
8
+ import { UnstakingStatus, YieldPoolType } from '@subwallet/extension-base/types';
9
+ import { formatNumber } from '@subwallet/extension-base/utils';
10
+
11
+ /* Description */
12
+ export function getWithdrawDescription(amount, symbol, stakingType) {
13
+ if (stakingType === YieldPoolType.LIQUID_STAKING) {
14
+ return `${amount} ${symbol} ready to withdraw from ${symbol} liquid staking. Click to withdraw now!`;
15
+ }
16
+ return `${amount} ${symbol} ready to withdraw from ${symbol} staking. Click to withdraw now!`;
17
+ }
18
+ export function getClaimDescription(amount, symbol) {
19
+ return `${amount} ${symbol} ready to claim from ${symbol} staking. Click to claim now!`;
20
+ }
21
+ export function getSendDescription(amount, symbol) {
22
+ return `You have just sent ${amount} ${symbol}`;
23
+ }
24
+ export function getReceiveDescription(amount, symbol) {
25
+ return `You have just received ${amount} ${symbol}`;
26
+ }
27
+ export function getAvailBridgeClaimDescription(amount, symbol) {
28
+ return `${amount} ${symbol} ready to claim from ${symbol} cross-chain transfer. Click to claim now!`;
29
+ }
30
+ /* Description */
31
+
32
+ export function getIsTabRead(notificationTab) {
33
+ if (notificationTab === NotificationTab.UNREAD) {
34
+ return false;
35
+ }
36
+ if (notificationTab === NotificationTab.READ) {
37
+ return true;
38
+ }
39
+ return undefined;
40
+ }
41
+ function createWithdrawNotification(amount, address, symbol, stakingSlug, stakingType) {
42
+ const actionType = NotificationActionType.WITHDRAW;
43
+ const extrinsicType = ExtrinsicType.STAKING_WITHDRAW;
44
+ const time = Date.now();
45
+ return {
46
+ id: `${actionType}___${stakingSlug}___${time}`,
47
+ title: NotificationTitleMap[actionType].replace('{{tokenSymbol}}', symbol),
48
+ description: NotificationDescriptionMap[actionType](amount, symbol, stakingType),
49
+ address,
50
+ time,
51
+ extrinsicType,
52
+ isRead: false,
53
+ actionType,
54
+ metadata: {
55
+ stakingType,
56
+ stakingSlug
57
+ }
58
+ };
59
+ }
60
+ export function createWithdrawNotifications(unstakingInfos, tokenInfo, address, stakingSlug, stakingType) {
61
+ const allWithdrawNotifications = [];
62
+ for (const unstaking of unstakingInfos) {
63
+ if (unstaking.status !== UnstakingStatus.CLAIMABLE) {
64
+ continue;
65
+ }
66
+ const rawClaimableAmount = unstaking.claimable;
67
+ const decimals = _getAssetDecimals(tokenInfo);
68
+ const symbol = _getAssetSymbol(tokenInfo);
69
+ const amount = formatNumber(rawClaimableAmount, decimals);
70
+ allWithdrawNotifications.push(createWithdrawNotification(amount, address, symbol, stakingSlug, stakingType));
71
+ }
72
+ return allWithdrawNotifications;
73
+ }
74
+ export function createClaimNotification(claimItemInfo, tokenInfo) {
75
+ const {
76
+ address,
77
+ slug,
78
+ type,
79
+ unclaimedReward = '0'
80
+ } = claimItemInfo;
81
+ const decimals = _getAssetDecimals(tokenInfo);
82
+ const symbol = _getAssetSymbol(tokenInfo);
83
+ const amount = formatNumber(unclaimedReward, decimals);
84
+ const actionType = NotificationActionType.CLAIM;
85
+ const extrinsicType = ExtrinsicType.STAKING_CLAIM_REWARD;
86
+ const time = Date.now();
87
+ return {
88
+ id: `${actionType}___${slug}___${time}`,
89
+ title: NotificationTitleMap[actionType].replace('{{tokenSymbol}}', symbol),
90
+ description: NotificationDescriptionMap[actionType](amount, symbol),
91
+ address,
92
+ time,
93
+ extrinsicType,
94
+ isRead: false,
95
+ actionType,
96
+ metadata: {
97
+ stakingType: type,
98
+ stakingSlug: slug
99
+ }
100
+ };
101
+ }
102
+
103
+ // todo: can refactor utils and const of avail bridge to a new file. Also check in /transfer/xcm/availBridge.ts file
104
+
105
+ export const AVAIL_BRIDGE_INDEXER = {
106
+ AVAIL_MAINNET: 'https://bridge-indexer.avail.so',
107
+ AVAIL_TESTNET: 'https://turing-bridge-indexer.fra.avail.so'
108
+ };
109
+ export const AVAIL_BRIDGE_API = {
110
+ AVAIL_MAINNET: 'https://bridge-api.avail.so',
111
+ AVAIL_TESTNET: 'https://turing-bridge-api.fra.avail.so'
112
+ };
113
+ export let AvailBridgeTransactionStatus;
114
+ (function (AvailBridgeTransactionStatus) {
115
+ AvailBridgeTransactionStatus["READY_TO_CLAIM"] = "READY_TO_CLAIM";
116
+ AvailBridgeTransactionStatus["CLAIMED"] = "CLAIMED";
117
+ AvailBridgeTransactionStatus["BRIDGED"] = "BRIDGED";
118
+ })(AvailBridgeTransactionStatus || (AvailBridgeTransactionStatus = {}));
119
+ export let AvailBridgeSourceChain;
120
+ (function (AvailBridgeSourceChain) {
121
+ AvailBridgeSourceChain["AVAIL"] = "AVAIL";
122
+ AvailBridgeSourceChain["ETHEREUM"] = "ETHEREUM";
123
+ })(AvailBridgeSourceChain || (AvailBridgeSourceChain = {}));
124
+ export async function fetchAllAvailBridgeClaimable(address, sourceChain, isTestnet) {
125
+ const transactions = [];
126
+ let isContinue = true;
127
+ let page = 0;
128
+ const pageSize = 100;
129
+ while (isContinue) {
130
+ const response = await fetchAvailBridgeTransactions(address, sourceChain, AvailBridgeTransactionStatus.READY_TO_CLAIM, pageSize, page, isTestnet);
131
+ if (!response) {
132
+ break;
133
+ }
134
+ transactions.push(...filterClaimableOfAddress(address, response.data.result));
135
+ isContinue = response.data.paginationData.hasNextPage;
136
+ page = page + 1;
137
+ }
138
+ return transactions;
139
+ }
140
+ export async function fetchAvailBridgeTransactions(userAddress, sourceChain, status, pageSize = 100, page = 0, isTestnet) {
141
+ const params = new URLSearchParams({
142
+ userAddress,
143
+ sourceChain,
144
+ status,
145
+ pageSize: pageSize.toString(),
146
+ page: page.toString()
147
+ });
148
+ try {
149
+ const api = isTestnet ? AVAIL_BRIDGE_INDEXER.AVAIL_TESTNET : AVAIL_BRIDGE_INDEXER.AVAIL_MAINNET;
150
+ const rawResponse = await fetch(`${api}/transactions?${params.toString()}`, {
151
+ method: 'GET',
152
+ headers: {
153
+ 'Content-Type': 'application/json',
154
+ 'Access-Control-Allow-Origin': '*'
155
+ },
156
+ credentials: 'omit'
157
+ });
158
+ if (!rawResponse.ok) {
159
+ console.error('Error fetching claimable bridge transactions');
160
+ return undefined;
161
+ }
162
+ return await rawResponse.json();
163
+ } catch (e) {
164
+ console.error(e);
165
+ return undefined;
166
+ }
167
+ }
168
+ export function filterClaimableOfAddress(address, transactions) {
169
+ return transactions.filter(transaction => transaction.receiverAddress.toLowerCase() === address.toLowerCase());
170
+ }
171
+ export function hrsToMillisecond(hours) {
172
+ return hours * 60 * 60 * 1000;
173
+ }
@@ -37,7 +37,9 @@ export declare class AccountContext {
37
37
  get currentAccount(): CurrentAccountInfo;
38
38
  saveCurrentAccountProxyId(proxyId: string, callback?: (data: CurrentAccountInfo) => void, preventOneAccount?: boolean): void;
39
39
  isUnifiedAccount(proxyId: string): boolean;
40
+ belongUnifiedAccount(address: string): string | undefined;
40
41
  addressesByProxyId(proxyId: string): string[];
42
+ getCurrentAccountProxyName(proxyId: string): string;
41
43
  accountsEdit(request: RequestAccountProxyEdit): boolean;
42
44
  checkNameExists({ name, proxyId }: RequestAccountNameValidate): ResponseAccountNameValidate;
43
45
  accountProxyForget(request: RequestAccountProxyForget): Promise<string[]>;
@@ -46,6 +48,7 @@ export declare class AccountContext {
46
48
  tonGetAllTonWalletContractVersion(request: RequestGetAllTonWalletContractVersion): ResponseGetAllTonWalletContractVersion;
47
49
  tonAccountChangeWalletContractVersion(request: RequestChangeTonWalletContractVersion): string;
48
50
  getDecodedAddresses(accountProxy?: string, allowGetAllAccount?: boolean): string[];
51
+ getAllAddresses(): string[];
49
52
  mnemonicCreateV2(request: RequestMnemonicCreateV2): Promise<ResponseMnemonicCreateV2>;
50
53
  mnemonicValidateV2(request: RequestMnemonicValidateV2): ResponseMnemonicValidateV2;
51
54
  accountsCreateSuriV2(request: RequestAccountCreateSuriV2): ResponseAccountCreateSuriV2;
@@ -55,9 +55,15 @@ export class AccountContext {
55
55
  isUnifiedAccount(proxyId) {
56
56
  return this.state.isUnifiedAccount(proxyId);
57
57
  }
58
+ belongUnifiedAccount(address) {
59
+ return this.state.belongUnifiedAccount(address);
60
+ }
58
61
  addressesByProxyId(proxyId) {
59
62
  return this.state.addressesByProxyId(proxyId);
60
63
  }
64
+ getCurrentAccountProxyName(proxyId) {
65
+ return this.state.getAccountProxyName(proxyId);
66
+ }
61
67
 
62
68
  /* Modify accounts */
63
69
 
@@ -96,6 +102,9 @@ export class AccountContext {
96
102
  getDecodedAddresses(accountProxy, allowGetAllAccount = true) {
97
103
  return this.state.getDecodedAddresses(accountProxy, allowGetAllAccount);
98
104
  }
105
+ getAllAddresses() {
106
+ return this.state.getAllAddresses();
107
+ }
99
108
 
100
109
  /* Get address for another service */
101
110
 
@@ -53,6 +53,7 @@ export declare class AccountState {
53
53
  * @param preventOneAccount - Optional flag to prevent setting the proxy ID if there is only one account.
54
54
  */
55
55
  saveCurrentAccountProxyId(_proxyId: string, callback?: (data: CurrentAccountInfo) => void, preventOneAccount?: boolean): void;
56
+ getAccountProxyName(proxyId: string): string;
56
57
  checkAddressExists(addresses: string[]): ExistsAccount | undefined;
57
58
  checkNameExists(name: string, proxyId?: string): boolean;
58
59
  getDuplicateAccountNames: (accounts: AccountProxy[]) => string[];
@@ -263,6 +263,10 @@ export class AccountState {
263
263
 
264
264
  /* Current account */
265
265
 
266
+ getAccountProxyName(proxyId) {
267
+ return this.accounts[proxyId].name;
268
+ }
269
+
266
270
  /* Check address exists */
267
271
  checkAddressExists(addresses) {
268
272
  for (const address of addresses) {
@@ -33,9 +33,17 @@ export default class SettingService {
33
33
  }
34
34
  getSettings(update) {
35
35
  this.settingsStore.get('Settings', value => {
36
+ var _value$notificationSe, _value$notificationSe2, _value$notificationSe3;
36
37
  update({
37
38
  ...DEFAULT_SETTING,
38
- ...(value || {})
39
+ ...(value || {}),
40
+ notificationSetup: {
41
+ isEnabled: (_value$notificationSe = value === null || value === void 0 ? void 0 : (_value$notificationSe2 = value.notificationSetup) === null || _value$notificationSe2 === void 0 ? void 0 : _value$notificationSe2.isEnabled) !== null && _value$notificationSe !== void 0 ? _value$notificationSe : DEFAULT_SETTING.notificationSetup.isEnabled,
42
+ showNotice: {
43
+ ...DEFAULT_SETTING.notificationSetup.showNotice,
44
+ ...((value === null || value === void 0 ? void 0 : (_value$notificationSe3 = value.notificationSetup) === null || _value$notificationSe3 === void 0 ? void 0 : _value$notificationSe3.showNotice) || {})
45
+ }
46
+ }
39
47
  });
40
48
  });
41
49
  }
@@ -1,4 +1,5 @@
1
1
  import { BrowserConfirmationType, LanguageType, ThemeNames, UiSettings, WalletUnlockType } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { NotificationSetup } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
2
3
  export declare const DEFAULT_THEME: ThemeNames;
3
4
  export declare const DEFAULT_NOTIFICATION_TYPE: BrowserConfirmationType;
4
5
  export declare const DEFAULT_AUTO_LOCK_TIME = 15;
@@ -10,4 +11,5 @@ export declare const DEFAULT_SHOW_ZERO_BALANCE = true;
10
11
  export declare const DEFAULT_SHOW_BALANCE = false;
11
12
  export declare const DEFAULT_ALL_LOGO = "";
12
13
  export declare const DEFAULT_CAMERA_ENABLE = false;
14
+ export declare const DEFAULT_NOTIFICATION_SETUP: NotificationSetup;
13
15
  export declare const DEFAULT_SETTING: UiSettings;