@subwallet/extension-base 1.3.3-0 → 1.3.4-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 (114) hide show
  1. package/background/KoniTypes.d.ts +13 -0
  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/background/handlers/Extension.js +110 -23
  11. package/cjs/koni/background/handlers/State.js +5 -2
  12. package/cjs/packageInfo.js +1 -1
  13. package/cjs/services/balance-service/helpers/process.js +2 -1
  14. package/cjs/services/balance-service/transfer/xcm/availBridge.js +198 -0
  15. package/cjs/services/balance-service/transfer/xcm/index.js +50 -5
  16. package/cjs/services/chain-service/handler/EvmApi.js +12 -21
  17. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +29 -0
  18. package/cjs/services/chain-service/index.js +44 -13
  19. package/cjs/services/chain-service/utils/index.js +20 -0
  20. package/cjs/services/earning-service/handlers/base.js +12 -3
  21. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +10 -2
  22. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +2 -0
  23. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +2 -0
  24. package/cjs/services/earning-service/handlers/native-staking/tao.js +10 -2
  25. package/cjs/services/earning-service/handlers/nomination-pool/index.js +9 -4
  26. package/cjs/services/earning-service/service.js +5 -0
  27. package/cjs/services/inapp-notification-service/consts.js +31 -0
  28. package/cjs/services/inapp-notification-service/index.js +260 -0
  29. package/cjs/services/inapp-notification-service/interfaces.js +32 -0
  30. package/cjs/services/inapp-notification-service/utils.js +197 -0
  31. package/cjs/services/keyring-service/context/account-context.js +9 -0
  32. package/cjs/services/keyring-service/context/state.js +4 -0
  33. package/cjs/services/setting-service/SettingService.js +9 -1
  34. package/cjs/services/setting-service/constants.js +16 -1
  35. package/cjs/services/storage-service/DatabaseService.js +42 -3
  36. package/cjs/services/storage-service/databases/index.js +3 -0
  37. package/cjs/services/storage-service/db-stores/InappNotification.js +81 -0
  38. package/cjs/services/transaction-service/index.js +13 -0
  39. package/cjs/types/avail-bridge/index.js +1 -0
  40. package/cjs/types/notification/index.js +1 -0
  41. package/cjs/utils/account/transform.js +9 -5
  42. package/cjs/utils/staticData/index.js +7 -2
  43. package/constants/blocked-actions-list.js +1 -2
  44. package/constants/index.d.ts +2 -0
  45. package/constants/index.js +3 -1
  46. package/constants/remind-notification-time.d.ts +2 -0
  47. package/constants/remind-notification-time.js +7 -0
  48. package/core/logic-validation/transfer.js +12 -6
  49. package/core/substrate/xcm-parser.d.ts +1 -0
  50. package/core/substrate/xcm-parser.js +12 -1
  51. package/koni/api/contract-handler/utils/avail_bridge_abi.json +1659 -0
  52. package/koni/api/contract-handler/utils/avail_test_bridge_abi.json +1692 -0
  53. package/koni/api/contract-handler/utils/index.d.ts +4 -0
  54. package/koni/api/contract-handler/utils/index.js +15 -0
  55. package/koni/background/handlers/Extension.d.ts +7 -0
  56. package/koni/background/handlers/Extension.js +112 -25
  57. package/koni/background/handlers/State.d.ts +2 -0
  58. package/koni/background/handlers/State.js +5 -2
  59. package/package.json +54 -6
  60. package/packageInfo.js +1 -1
  61. package/services/balance-service/helpers/process.js +2 -1
  62. package/services/balance-service/transfer/xcm/availBridge.d.ts +45 -0
  63. package/services/balance-service/transfer/xcm/availBridge.js +186 -0
  64. package/services/balance-service/transfer/xcm/index.d.ts +8 -8
  65. package/services/balance-service/transfer/xcm/index.js +46 -5
  66. package/services/chain-service/handler/EvmApi.js +12 -21
  67. package/services/chain-service/handler/SubstrateChainHandler.d.ts +2 -0
  68. package/services/chain-service/handler/SubstrateChainHandler.js +29 -0
  69. package/services/chain-service/index.d.ts +2 -0
  70. package/services/chain-service/index.js +45 -14
  71. package/services/chain-service/types.d.ts +2 -1
  72. package/services/chain-service/utils/index.d.ts +3 -0
  73. package/services/chain-service/utils/index.js +14 -0
  74. package/services/earning-service/handlers/base.d.ts +2 -0
  75. package/services/earning-service/handlers/base.js +9 -0
  76. package/services/earning-service/handlers/native-staking/amplitude.js +10 -2
  77. package/services/earning-service/handlers/native-staking/para-chain.js +2 -0
  78. package/services/earning-service/handlers/native-staking/relay-chain.js +2 -0
  79. package/services/earning-service/handlers/native-staking/tao.d.ts +4 -0
  80. package/services/earning-service/handlers/native-staking/tao.js +5 -1
  81. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -1
  82. package/services/earning-service/handlers/nomination-pool/index.js +9 -4
  83. package/services/earning-service/service.d.ts +2 -0
  84. package/services/earning-service/service.js +5 -0
  85. package/services/inapp-notification-service/consts.d.ts +18 -0
  86. package/services/inapp-notification-service/consts.js +22 -0
  87. package/services/inapp-notification-service/index.d.ts +37 -0
  88. package/services/inapp-notification-service/index.js +252 -0
  89. package/services/inapp-notification-service/interfaces.d.ts +77 -0
  90. package/services/inapp-notification-service/interfaces.js +24 -0
  91. package/services/inapp-notification-service/utils.d.ts +55 -0
  92. package/services/inapp-notification-service/utils.js +173 -0
  93. package/services/keyring-service/context/account-context.d.ts +3 -0
  94. package/services/keyring-service/context/account-context.js +9 -0
  95. package/services/keyring-service/context/state.d.ts +1 -0
  96. package/services/keyring-service/context/state.js +4 -0
  97. package/services/setting-service/SettingService.js +9 -1
  98. package/services/setting-service/constants.d.ts +2 -0
  99. package/services/setting-service/constants.js +15 -0
  100. package/services/storage-service/DatabaseService.d.ts +15 -0
  101. package/services/storage-service/DatabaseService.js +42 -3
  102. package/services/storage-service/databases/index.d.ts +2 -0
  103. package/services/storage-service/databases/index.js +3 -0
  104. package/services/storage-service/db-stores/InappNotification.d.ts +14 -0
  105. package/services/storage-service/db-stores/InappNotification.js +73 -0
  106. package/services/transaction-service/index.js +13 -0
  107. package/types/avail-bridge/index.d.ts +6 -0
  108. package/types/avail-bridge/index.js +1 -0
  109. package/types/notification/index.d.ts +9 -0
  110. package/types/notification/index.js +1 -0
  111. package/utils/account/transform.js +9 -5
  112. package/utils/staticData/index.d.ts +5 -1
  113. package/utils/staticData/index.js +5 -2
  114. package/utils/staticData/remindNotificationTime.json +1 -0
@@ -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;
@@ -14,6 +14,20 @@ export const DEFAULT_SHOW_ZERO_BALANCE = true;
14
14
  export const DEFAULT_SHOW_BALANCE = false;
15
15
  export const DEFAULT_ALL_LOGO = '';
16
16
  export const DEFAULT_CAMERA_ENABLE = false;
17
+ export const DEFAULT_NOTIFICATION_SETUP = {
18
+ isEnabled: true,
19
+ showNotice: {
20
+ // send: true,
21
+ // receive: true,
22
+ earningClaim: true,
23
+ earningWithdraw: true,
24
+ availBridgeClaim: true
25
+ // isHideWithdraw: false, // todo: just for test, remove later
26
+ // isHideMarketing: false,
27
+ // isHideAnnouncement: false
28
+ }
29
+ };
30
+
17
31
  export const DEFAULT_SETTING = {
18
32
  language: DEFAULT_LANGUAGE,
19
33
  currency: DEFAULT_CURRENCY,
@@ -26,5 +40,6 @@ export const DEFAULT_SETTING = {
26
40
  camera: DEFAULT_CAMERA_ENABLE,
27
41
  timeAutoLock: DEFAULT_AUTO_LOCK_TIME,
28
42
  enableChainPatrol: DEFAULT_CHAIN_PATROL_ENABLE,
43
+ notificationSetup: DEFAULT_NOTIFICATION_SETUP,
29
44
  walletReference: ''
30
45
  };
@@ -1,16 +1,19 @@
1
1
  import { _ChainAsset } from '@subwallet/chain-list/types';
2
2
  import { ChainStakingMetadata, CrowdloanItem, MantaPayConfig, NftCollection, NftItem, NominatorMetadata, PriceJson, StakingItem, StakingType, TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { EventService } from '@subwallet/extension-base/services/event-service';
4
+ import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
4
5
  import { IBalance, ICampaign, IChain, INft } from '@subwallet/extension-base/services/storage-service/databases';
5
6
  import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
6
7
  import CampaignStore from '@subwallet/extension-base/services/storage-service/db-stores/Campaign';
7
8
  import ChainStakingMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata';
9
+ import InappNotificationStore from '@subwallet/extension-base/services/storage-service/db-stores/InappNotification';
8
10
  import MantaPayStore from '@subwallet/extension-base/services/storage-service/db-stores/MantaPay';
9
11
  import NominatorMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata';
10
12
  import { HistoryQuery } from '@subwallet/extension-base/services/storage-service/db-stores/Transaction';
11
13
  import YieldPoolStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore';
12
14
  import YieldPositionStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPositionStore';
13
15
  import { BalanceItem, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
16
+ import { GetNotificationParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
14
17
  import { Subscription } from 'dexie';
15
18
  import { DexieExportJsonStructure } from 'dexie-export-import';
16
19
  export declare const DEXIE_BACKUP_TABLES: string[];
@@ -35,6 +38,7 @@ export default class DatabaseService {
35
38
  nominatorMetadata: NominatorMetadataStore;
36
39
  mantaPay: MantaPayStore;
37
40
  campaign: CampaignStore;
41
+ inappNotification: InappNotificationStore;
38
42
  };
39
43
  private logger;
40
44
  private nftSubscription;
@@ -106,6 +110,7 @@ export default class DatabaseService {
106
110
  removeYieldPositionByChains(chains: string[]): import("dexie").PromiseExtended<number>;
107
111
  updateYieldPosition(data: YieldPositionInfo): Promise<void>;
108
112
  updateYieldPositions(data: YieldPositionInfo[]): Promise<void>;
113
+ getYieldPositions(): Promise<YieldPositionInfo[]>;
109
114
  getYieldPositionByAddress(addresses: string[]): Promise<YieldPositionInfo[]>;
110
115
  subscribeYieldPosition(addresses: string[], callback: (data: YieldPositionInfo[]) => void): Subscription;
111
116
  getYieldNominationPoolPosition(addresses: string[], chains: string[]): Promise<YieldPositionInfo[]>;
@@ -114,6 +119,16 @@ export default class DatabaseService {
114
119
  getProcessingCampaign(): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData[]>;
115
120
  getCampaign(slug: string): Promise<import("@subwallet/extension-base/background/KoniTypes").CampaignData | undefined>;
116
121
  upsertCampaign(campaign: ICampaign): import("dexie").PromiseExtended<unknown>;
122
+ getNotification(id: string): Promise<_NotificationInfo | undefined>;
123
+ updateNotification(notification: _NotificationInfo): Promise<unknown>;
124
+ getNotificationsByParams(params: GetNotificationParams): Promise<_NotificationInfo[]>;
125
+ cleanUpOldNotifications(overdueTime: number): Promise<number>;
126
+ subscribeUnreadNotificationsCountMap(): import("dexie").Observable<Record<string, number>>;
127
+ getUnreadNotificationsCountMap(): Promise<Record<string, number>>;
128
+ upsertNotifications(notifications: _NotificationInfo[]): Promise<unknown>;
129
+ markAllRead(proxyId: string): import("dexie").PromiseExtended<number>;
130
+ switchReadStatus(params: RequestSwitchStatusParams): import("dexie").PromiseExtended<number>;
131
+ removeAccountNotifications(proxyId: string): import("dexie").PromiseExtended<number>;
117
132
  exportDB(): Promise<string>;
118
133
  importDB(data: string): Promise<boolean>;
119
134
  getExportJson(): Promise<DexieExportJsonStructure>;
@@ -6,6 +6,7 @@ import KoniDatabase from '@subwallet/extension-base/services/storage-service/dat
6
6
  import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
7
7
  import CampaignStore from '@subwallet/extension-base/services/storage-service/db-stores/Campaign';
8
8
  import ChainStakingMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata';
9
+ import InappNotificationStore from '@subwallet/extension-base/services/storage-service/db-stores/InappNotification';
9
10
  import MantaPayStore from '@subwallet/extension-base/services/storage-service/db-stores/MantaPay';
10
11
  import NominatorMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata';
11
12
  import YieldPoolStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore';
@@ -45,11 +46,13 @@ export default class DatabaseService {
45
46
  chainStakingMetadata: new ChainStakingMetadataStore(this._db.chainStakingMetadata),
46
47
  nominatorMetadata: new NominatorMetadataStore(this._db.nominatorMetadata),
47
48
  mantaPay: new MantaPayStore(this._db.mantaPay),
48
- campaign: new CampaignStore(this._db.campaign)
49
+ campaign: new CampaignStore(this._db.campaign),
49
50
  // assetRef: new AssetRefStore(this._db.assetRef)
51
+
52
+ // inapp notification
53
+ inappNotification: new InappNotificationStore(this._db.inappNotification)
50
54
  };
51
55
  }
52
-
53
56
  async updatePriceStore(priceData) {
54
57
  await this.stores.price.table.put(priceData);
55
58
  }
@@ -358,7 +361,7 @@ export default class DatabaseService {
358
361
  }
359
362
  async resetWallet(resetAll) {
360
363
  return new Promise((resolve, reject) => {
361
- const stores = [this.stores.balance, this.stores.nft, this.stores.nftCollection, this.stores.crowdloan, this.stores.staking, this.stores.transaction, this.stores.nominatorMetadata];
364
+ const stores = [this.stores.balance, this.stores.nft, this.stores.nftCollection, this.stores.crowdloan, this.stores.staking, this.stores.transaction, this.stores.nominatorMetadata, this.stores.inappNotification];
362
365
  if (resetAll) {
363
366
  stores.push(this.stores.chain, this.stores.asset);
364
367
  }
@@ -445,6 +448,9 @@ export default class DatabaseService {
445
448
  async updateYieldPositions(data) {
446
449
  await this.stores.yieldPosition.bulkUpsert(data);
447
450
  }
451
+ async getYieldPositions() {
452
+ return this.stores.yieldPosition.getAll();
453
+ }
448
454
  async getYieldPositionByAddress(addresses) {
449
455
  return this.stores.yieldPosition.getByAddress(addresses);
450
456
  }
@@ -474,6 +480,39 @@ export default class DatabaseService {
474
480
  upsertCampaign(campaign) {
475
481
  return this.stores.campaign.upsertCampaign(campaign);
476
482
  }
483
+
484
+ /* Inapp Notification */
485
+
486
+ getNotification(id) {
487
+ return this.stores.inappNotification.getNotificationInfo(id);
488
+ }
489
+ updateNotification(notification) {
490
+ return this.stores.inappNotification.upsert(notification);
491
+ }
492
+ async getNotificationsByParams(params) {
493
+ return this.stores.inappNotification.getNotificationsByParams(params);
494
+ }
495
+ cleanUpOldNotifications(overdueTime) {
496
+ return this.stores.inappNotification.cleanUpOldNotifications(overdueTime);
497
+ }
498
+ subscribeUnreadNotificationsCountMap() {
499
+ return this.stores.inappNotification.subscribeUnreadNotificationsCount();
500
+ }
501
+ getUnreadNotificationsCountMap() {
502
+ return this.stores.inappNotification.getUnreadNotificationsCountMap();
503
+ }
504
+ upsertNotifications(notifications) {
505
+ return this.stores.inappNotification.bulkUpsert(notifications);
506
+ }
507
+ markAllRead(proxyId) {
508
+ return this.stores.inappNotification.markAllRead(proxyId);
509
+ }
510
+ switchReadStatus(params) {
511
+ return this.stores.inappNotification.switchReadStatus(params);
512
+ }
513
+ removeAccountNotifications(proxyId) {
514
+ return this.stores.inappNotification.removeAccountNotifications(proxyId);
515
+ }
477
516
  async exportDB() {
478
517
  const blob = await exportDB(this._db, {
479
518
  filter: (table, value, key) => {
@@ -1,5 +1,6 @@
1
1
  import { _AssetRef, _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { CampaignData, ChainStakingMetadata, CrowdloanItem, MetadataItem, NftCollection, NftItem, NominatorMetadata, PriceJson, StakingItem, TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
3
4
  import { BalanceItem, YieldPoolInfo, YieldPositionInfo } from '@subwallet/extension-base/types';
4
5
  import Dexie, { Table } from 'dexie';
5
6
  export declare const DEFAULT_DATABASE = "SubWalletDB_v2";
@@ -59,6 +60,7 @@ export default class KoniDatabase extends Dexie {
59
60
  mantaPay: Table<IMantaPayLedger, object>;
60
61
  campaign: Table<ICampaign, object>;
61
62
  keyValue: Table<IKeyValue, object>;
63
+ inappNotification: Table<_NotificationInfo, object>;
62
64
  private schemaVersion;
63
65
  constructor(name?: string, schemaVersion?: number);
64
66
  private conditionalVersion;
@@ -40,6 +40,9 @@ export default class KoniDatabase extends Dexie {
40
40
  this.conditionalVersion(6, {
41
41
  keyValue: 'key'
42
42
  });
43
+ this.conditionalVersion(7, {
44
+ inappNotification: 'id, address, proxyId, [proxyId+actionType], actionType'
45
+ });
43
46
  }
44
47
  conditionalVersion(version, schema, upgrade) {
45
48
  if (this.schemaVersion != null && this.schemaVersion < version) {
@@ -0,0 +1,14 @@
1
+ import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
2
+ import BaseStore from '@subwallet/extension-base/services/storage-service/db-stores/BaseStore';
3
+ import { GetNotificationParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
4
+ export default class InappNotificationStore extends BaseStore<_NotificationInfo> {
5
+ getNotificationInfo(id: string): Promise<_NotificationInfo | undefined>;
6
+ getAll(): Promise<_NotificationInfo[]>;
7
+ getNotificationsByParams(params: GetNotificationParams): Promise<_NotificationInfo[]>;
8
+ cleanUpOldNotifications(overdueTime: number): Promise<number>;
9
+ subscribeUnreadNotificationsCount(): import("dexie").Observable<Record<string, number>>;
10
+ getUnreadNotificationsCountMap(): Promise<Record<string, number>>;
11
+ markAllRead(proxyId: string): import("dexie").PromiseExtended<number>;
12
+ switchReadStatus(params: RequestSwitchStatusParams): import("dexie").PromiseExtended<number>;
13
+ removeAccountNotifications(proxyId: string): import("dexie").PromiseExtended<number>;
14
+ }
@@ -0,0 +1,73 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
5
+ import { NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
6
+ import { getIsTabRead } from '@subwallet/extension-base/services/inapp-notification-service/utils';
7
+ import BaseStore from '@subwallet/extension-base/services/storage-service/db-stores/BaseStore';
8
+ import { liveQuery } from 'dexie';
9
+ export default class InappNotificationStore extends BaseStore {
10
+ async getNotificationInfo(id) {
11
+ return this.table.get(id);
12
+ }
13
+ async getAll() {
14
+ return this.table.toArray();
15
+ }
16
+ async getNotificationsByParams(params) {
17
+ const {
18
+ notificationTab,
19
+ proxyId
20
+ } = params;
21
+ const isAllAccount = proxyId === ALL_ACCOUNT_KEY;
22
+ const isTabAll = notificationTab === NotificationTab.ALL;
23
+ if (isTabAll && isAllAccount) {
24
+ return this.getAll();
25
+ }
26
+ const filteredTable = this.table.filter(item => {
27
+ const matchesProxyId = item.proxyId === proxyId;
28
+ const matchesReadStatus = item.isRead === getIsTabRead(notificationTab);
29
+ if (isTabAll) {
30
+ return matchesProxyId;
31
+ }
32
+ if (isAllAccount) {
33
+ return matchesReadStatus;
34
+ }
35
+ return matchesProxyId && matchesReadStatus;
36
+ });
37
+ return filteredTable.toArray();
38
+ }
39
+ async cleanUpOldNotifications(overdueTime) {
40
+ const currentTimestamp = Date.now();
41
+ return this.table.filter(item => item.time <= currentTimestamp - overdueTime).delete();
42
+ }
43
+ subscribeUnreadNotificationsCount() {
44
+ return liveQuery(async () => {
45
+ return await this.getUnreadNotificationsCountMap();
46
+ });
47
+ }
48
+ async getUnreadNotificationsCountMap() {
49
+ const unreadNotifications = await this.table.filter(item => !item.isRead).toArray();
50
+ return unreadNotifications.reduce((countMap, item) => {
51
+ countMap[item.proxyId] = (countMap[item.proxyId] || 0) + 1;
52
+ return countMap;
53
+ }, {});
54
+ }
55
+ markAllRead(proxyId) {
56
+ if (proxyId === ALL_ACCOUNT_KEY) {
57
+ return this.table.toCollection().modify({
58
+ isRead: true
59
+ });
60
+ }
61
+ return this.table.where('proxyId').equalsIgnoreCase(proxyId).modify({
62
+ isRead: true
63
+ });
64
+ }
65
+ switchReadStatus(params) {
66
+ return this.table.where('id').equals(params.id).modify({
67
+ isRead: !params.isRead
68
+ });
69
+ }
70
+ removeAccountNotifications(proxyId) {
71
+ return this.table.where('proxyId').equalsIgnoreCase(proxyId).delete();
72
+ }
73
+ }
@@ -578,6 +578,19 @@ export default class TransactionService {
578
578
  historyItem.additionalInfo = data;
579
579
  break;
580
580
  }
581
+ case ExtrinsicType.CLAIM_AVAIL_BRIDGE:
582
+ {
583
+ const data = parseTransactionData(transaction.data); // TODO: switch by provider
584
+ const metadata = data.notification.metadata;
585
+ const claimAsset = this.state.chainService.getAssetBySlug(metadata.tokenSlug);
586
+ historyItem.amount = {
587
+ value: metadata.amount,
588
+ symbol: _getAssetSymbol(claimAsset),
589
+ decimals: _getAssetDecimals(claimAsset)
590
+ };
591
+ historyItem.additionalInfo = data;
592
+ break;
593
+ }
581
594
  case ExtrinsicType.UNKNOWN:
582
595
  break;
583
596
  }
@@ -0,0 +1,6 @@
1
+ import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
2
+ export interface RequestClaimAvailBridge {
3
+ address: string;
4
+ chain: string;
5
+ notification: _NotificationInfo;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
2
+ export interface GetNotificationParams {
3
+ proxyId: string;
4
+ notificationTab: NotificationTab;
5
+ }
6
+ export interface RequestSwitchStatusParams {
7
+ id: string;
8
+ isRead: boolean;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -135,23 +135,24 @@ const EARN_QDOT_ACTIONS = [ExtrinsicType.MINT_QDOT, ExtrinsicType.REDEEM_QDOT, E
135
135
  const EARN_STDOT_ACTIONS = [ExtrinsicType.MINT_STDOT, ExtrinsicType.REDEEM_STDOT, ExtrinsicType.UNSTAKE_STDOT];
136
136
  const EARN_VMANTA_ACTIONS = [ExtrinsicType.MINT_VMANTA, ExtrinsicType.REDEEM_VMANTA, ExtrinsicType.UNSTAKE_VMANTA];
137
137
  const EVM_ACTIONS = [ExtrinsicType.TOKEN_SPENDING_APPROVAL, ExtrinsicType.EVM_EXECUTE];
138
+ const CLAIM_AVAIL_BRIDGE = [ExtrinsicType.CLAIM_AVAIL_BRIDGE];
138
139
  const OTHER_ACTIONS = [ExtrinsicType.TRANSFER_XCM, ExtrinsicType.SEND_NFT, ExtrinsicType.SWAP, ExtrinsicType.CROWDLOAN];
139
140
  export const getAccountTransactionActions = (signMode, networkType, type, _meta, _specialNetwork) => {
140
141
  if ([AccountSignMode.PASSWORD, AccountSignMode.INJECTED].includes(signMode)) {
141
142
  switch (networkType) {
142
143
  case AccountChainType.SUBSTRATE:
143
- return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_VDOT_ACTIONS, ...EARN_LDOT_ACTIONS, ...EARN_SDOT_ACTIONS, ...EARN_QDOT_ACTIONS, ...EARN_VMANTA_ACTIONS, ...OTHER_ACTIONS];
144
+ return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_VDOT_ACTIONS, ...EARN_LDOT_ACTIONS, ...EARN_SDOT_ACTIONS, ...EARN_QDOT_ACTIONS, ...EARN_VMANTA_ACTIONS, ...CLAIM_AVAIL_BRIDGE, ...OTHER_ACTIONS];
144
145
  case AccountChainType.ETHEREUM:
145
- return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_STDOT_ACTIONS, ...OTHER_ACTIONS, ...EVM_ACTIONS];
146
+ return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_STDOT_ACTIONS, ...OTHER_ACTIONS, ...CLAIM_AVAIL_BRIDGE, ...EVM_ACTIONS];
146
147
  case AccountChainType.TON:
147
148
  return [...BASE_TRANSFER_ACTIONS];
148
149
  }
149
150
  } else if (signMode === AccountSignMode.QR) {
150
151
  switch (networkType) {
151
152
  case AccountChainType.SUBSTRATE:
152
- return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_VDOT_ACTIONS, ...EARN_LDOT_ACTIONS, ...EARN_SDOT_ACTIONS, ...EARN_QDOT_ACTIONS, ...EARN_VMANTA_ACTIONS, ...OTHER_ACTIONS];
153
+ return [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_VDOT_ACTIONS, ...EARN_LDOT_ACTIONS, ...EARN_SDOT_ACTIONS, ...EARN_QDOT_ACTIONS, ...EARN_VMANTA_ACTIONS, ...CLAIM_AVAIL_BRIDGE, ...OTHER_ACTIONS];
153
154
  case AccountChainType.ETHEREUM:
154
- return [...(isProductionMode ? [] : [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_STDOT_ACTIONS, ...OTHER_ACTIONS, ...EVM_ACTIONS])];
155
+ return [...(isProductionMode ? [] : [...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, ...EARN_STDOT_ACTIONS, ...CLAIM_AVAIL_BRIDGE, ...OTHER_ACTIONS, ...EVM_ACTIONS])];
155
156
  case AccountChainType.TON:
156
157
  return [];
157
158
  }
@@ -164,7 +165,7 @@ export const getAccountTransactionActions = (signMode, networkType, type, _meta,
164
165
  // ...EARN_QDOT_ACTIONS,
165
166
  ...OTHER_ACTIONS];
166
167
  case AccountChainType.ETHEREUM:
167
- return [...BASE_TRANSFER_ACTIONS, ...EARN_STDOT_ACTIONS, ...EVM_ACTIONS, ExtrinsicType.STAKING_WITHDRAW,
168
+ return [...BASE_TRANSFER_ACTIONS, ...EARN_STDOT_ACTIONS, ...EVM_ACTIONS, ...CLAIM_AVAIL_BRIDGE, ExtrinsicType.STAKING_WITHDRAW,
168
169
  // For liquid staking
169
170
  ExtrinsicType.SEND_NFT, ExtrinsicType.SWAP];
170
171
  case AccountChainType.TON:
@@ -202,6 +203,9 @@ export const getAccountTransactionActions = (signMode, networkType, type, _meta,
202
203
  if (['polkadot', 'kusama', 'statemint', 'statemine'].includes(specialNetwork)) {
203
204
  result.push(ExtrinsicType.TRANSFER_XCM);
204
205
  }
206
+ if (['availTuringTest', 'avail_mainnet'].includes(specialNetwork)) {
207
+ result.push(...CLAIM_AVAIL_BRIDGE);
208
+ }
205
209
  return result;
206
210
  }
207
211
  return [];