@subwallet/extension-base 1.1.16-1 → 1.1.18-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 (81) hide show
  1. package/background/KoniTypes.d.ts +67 -1
  2. package/background/KoniTypes.js +5 -0
  3. package/cjs/background/KoniTypes.js +7 -1
  4. package/cjs/constants/index.js +6 -3
  5. package/cjs/koni/api/dotsama/crowdloan.js +106 -60
  6. package/cjs/koni/api/nft/config.js +5 -1
  7. package/cjs/koni/api/nft/index.js +3 -0
  8. package/cjs/koni/api/nft/vara_nft/index.js +107 -0
  9. package/cjs/koni/background/handlers/Extension.js +48 -0
  10. package/cjs/koni/background/handlers/State.js +25 -33
  11. package/cjs/koni/background/subscription.js +6 -2
  12. package/cjs/packageInfo.js +1 -1
  13. package/cjs/services/campaign-service/helpers.js +61 -0
  14. package/cjs/services/campaign-service/index.js +142 -0
  15. package/cjs/services/campaign-service/types.js +1 -0
  16. package/cjs/services/chain-service/constants.js +3 -2
  17. package/cjs/services/chain-service/index.js +2 -0
  18. package/cjs/services/event-service/index.js +2 -0
  19. package/cjs/services/migration-service/index.js +4 -1
  20. package/cjs/services/migration-service/scripts/EnableChain.js +18 -0
  21. package/cjs/services/migration-service/scripts/EnableVaraChain.js +15 -0
  22. package/cjs/services/migration-service/scripts/MigrateEthProvider.js +5 -20
  23. package/cjs/services/migration-service/scripts/MigratePioneerProvider.js +17 -0
  24. package/cjs/services/migration-service/scripts/MigrateProvider.js +29 -0
  25. package/cjs/services/migration-service/scripts/index.js +5 -1
  26. package/cjs/services/notification-service/NotificationService.js +20 -6
  27. package/cjs/services/storage-service/DatabaseService.js +18 -1
  28. package/cjs/services/storage-service/databases/index.js +3 -0
  29. package/cjs/services/storage-service/db-stores/Campaign.js +35 -0
  30. package/cjs/services/transaction-service/index.js +6 -1
  31. package/constants/index.d.ts +1 -0
  32. package/constants/index.js +1 -0
  33. package/koni/api/dotsama/crowdloan.d.ts +7 -6
  34. package/koni/api/dotsama/crowdloan.js +103 -51
  35. package/koni/api/nft/config.d.ts +1 -0
  36. package/koni/api/nft/config.js +4 -0
  37. package/koni/api/nft/index.js +3 -0
  38. package/koni/api/nft/vara_nft/index.d.ts +9 -0
  39. package/koni/api/nft/vara_nft/index.js +99 -0
  40. package/koni/background/handlers/Extension.d.ts +2 -0
  41. package/koni/background/handlers/Extension.js +48 -1
  42. package/koni/background/handlers/State.d.ts +2 -0
  43. package/koni/background/handlers/State.js +4 -11
  44. package/koni/background/subscription.js +6 -2
  45. package/package.json +51 -6
  46. package/packageInfo.js +1 -1
  47. package/services/campaign-service/helpers.d.ts +3 -0
  48. package/services/campaign-service/helpers.js +54 -0
  49. package/services/campaign-service/index.d.ts +11 -0
  50. package/services/campaign-service/index.js +134 -0
  51. package/services/campaign-service/types.d.ts +34 -0
  52. package/services/campaign-service/types.js +1 -0
  53. package/services/chain-service/constants.d.ts +1 -0
  54. package/services/chain-service/constants.js +3 -2
  55. package/services/chain-service/index.js +2 -0
  56. package/services/chain-service/types.d.ts +3 -1
  57. package/services/event-service/index.d.ts +2 -0
  58. package/services/event-service/index.js +2 -0
  59. package/services/event-service/types.d.ts +2 -0
  60. package/services/migration-service/index.d.ts +3 -1
  61. package/services/migration-service/index.js +4 -1
  62. package/services/migration-service/scripts/EnableChain.d.ts +5 -0
  63. package/services/migration-service/scripts/EnableChain.js +10 -0
  64. package/services/migration-service/scripts/EnableVaraChain.d.ts +4 -0
  65. package/services/migration-service/scripts/EnableVaraChain.js +7 -0
  66. package/services/migration-service/scripts/MigrateEthProvider.d.ts +5 -3
  67. package/services/migration-service/scripts/MigrateEthProvider.js +5 -20
  68. package/services/migration-service/scripts/MigratePioneerProvider.d.ts +6 -0
  69. package/services/migration-service/scripts/MigratePioneerProvider.js +9 -0
  70. package/services/migration-service/scripts/MigrateProvider.d.ts +7 -0
  71. package/services/migration-service/scripts/MigrateProvider.js +21 -0
  72. package/services/migration-service/scripts/index.js +5 -1
  73. package/services/notification-service/NotificationService.d.ts +2 -2
  74. package/services/notification-service/NotificationService.js +20 -6
  75. package/services/storage-service/DatabaseService.d.ts +7 -1
  76. package/services/storage-service/DatabaseService.js +18 -1
  77. package/services/storage-service/databases/index.d.ts +3 -1
  78. package/services/storage-service/databases/index.js +3 -0
  79. package/services/storage-service/db-stores/Campaign.d.ts +9 -0
  80. package/services/storage-service/db-stores/Campaign.js +27 -0
  81. package/services/transaction-service/index.js +6 -1
@@ -8,6 +8,7 @@ exports.default = void 0;
8
8
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
9
9
  var _databases = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/databases"));
10
10
  var _dbStores = require("@subwallet/extension-base/services/storage-service/db-stores");
11
+ var _Campaign = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/Campaign"));
11
12
  var _ChainStakingMetadata = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata"));
12
13
  var _MantaPay = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/MantaPay"));
13
14
  var _NominatorMetadata = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata"));
@@ -41,7 +42,8 @@ class DatabaseService {
41
42
  // staking
42
43
  chainStakingMetadata: new _ChainStakingMetadata.default(this._db.chainStakingMetadata),
43
44
  nominatorMetadata: new _NominatorMetadata.default(this._db.nominatorMetadata),
44
- mantaPay: new _MantaPay.default(this._db.mantaPay)
45
+ mantaPay: new _MantaPay.default(this._db.mantaPay),
46
+ campaign: new _Campaign.default(this._db.campaign)
45
47
  };
46
48
  }
47
49
  async updatePriceStore(priceData) {
@@ -270,5 +272,20 @@ class DatabaseService {
270
272
  async getMantaPayFirstConfig(chain) {
271
273
  return this.stores.mantaPay.getFirstConfig(chain);
272
274
  }
275
+
276
+ /* Campaign */
277
+
278
+ subscribeProcessingCampaign() {
279
+ return this.stores.campaign.subscribeProcessingCampaign();
280
+ }
281
+ getProcessingCampaign() {
282
+ return this.stores.campaign.getProcessingCampaign();
283
+ }
284
+ getCampaign(slug) {
285
+ return this.stores.campaign.getCampaign(slug);
286
+ }
287
+ upsertCampaign(campaign) {
288
+ return this.stores.campaign.upsertCampaign(campaign);
289
+ }
273
290
  }
274
291
  exports.default = DatabaseService;
@@ -39,6 +39,9 @@ class KoniDatabase extends _dexie.default {
39
39
  this.conditionalVersion(3, {
40
40
  mantaPay: 'key, chain'
41
41
  });
42
+ this.conditionalVersion(4, {
43
+ campaign: 'slug'
44
+ });
42
45
  }
43
46
  conditionalVersion(version, schema, upgrade) {
44
47
  if (this.schemaVersion != null && this.schemaVersion < version) {
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _BaseStore = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/BaseStore"));
9
+ var _dexie = require("dexie");
10
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
11
+ // SPDX-License-Identifier: Apache-2.0
12
+
13
+ const filterProcessing = campaign => {
14
+ const now = new Date().getTime();
15
+ const isExpired = now <= campaign.startTime || now >= campaign.endTime;
16
+ return !(campaign.isDone || isExpired);
17
+ };
18
+ class CampaignStore extends _BaseStore.default {
19
+ async getAll() {
20
+ return this.table.toArray();
21
+ }
22
+ async getCampaign(slug) {
23
+ return this.table.get(slug);
24
+ }
25
+ async getProcessingCampaign() {
26
+ return (await this.table.toArray()).filter(filterProcessing);
27
+ }
28
+ subscribeProcessingCampaign() {
29
+ return (0, _dexie.liveQuery)(() => this.table.filter(filterProcessing).toArray());
30
+ }
31
+ upsertCampaign(campaign) {
32
+ return this.table.put(campaign);
33
+ }
34
+ }
35
+ exports.default = CampaignStore;
@@ -75,6 +75,7 @@ class TransactionService {
75
75
  address,
76
76
  chain,
77
77
  edAsWarning,
78
+ extrinsicType,
78
79
  isTransferAll,
79
80
  transaction
80
81
  } = validation;
@@ -84,7 +85,11 @@ class TransactionService {
84
85
 
85
86
  // Return unsupported error if not found transaction
86
87
  if (!transaction) {
87
- validation.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.UNSUPPORTED));
88
+ if (extrinsicType === _KoniTypes.ExtrinsicType.SEND_NFT) {
89
+ validation.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.UNSUPPORTED, (0, _i18next.t)('This feature is not yet available for this NFT')));
90
+ } else {
91
+ validation.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.UNSUPPORTED));
92
+ }
88
93
  }
89
94
  const validationResponse = {
90
95
  status: undefined,
@@ -20,5 +20,6 @@ export declare const ALL_GENESIS_HASH: null;
20
20
  export declare const IGNORE_GET_SUBSTRATE_FEATURES_LIST: string[];
21
21
  export declare const IGNORE_QR_SIGNER: string[];
22
22
  export declare const XCM_MIN_AMOUNT_RATIO = 1.2;
23
+ export declare const MARKETING_CAMPAIGN_URL: string;
23
24
  export * from './staking';
24
25
  export * from './storage';
@@ -23,5 +23,6 @@ export const ALL_GENESIS_HASH = null;
23
23
  export const IGNORE_GET_SUBSTRATE_FEATURES_LIST = ['astarEvm', 'ethereum', 'ethereum_goerli', 'binance', 'binance_test', 'boba_rinkeby', 'boba', 'bobabase', 'bobabeam'];
24
24
  export const IGNORE_QR_SIGNER = [];
25
25
  export const XCM_MIN_AMOUNT_RATIO = 1.2;
26
+ export const MARKETING_CAMPAIGN_URL = process.env.MARKETING_CAMPAIGN_URL || '';
26
27
  export * from "./staking.js";
27
28
  export * from "./storage.js";
@@ -1,7 +1,8 @@
1
- import { _ChainInfo } from '@subwallet/chain-list/types';
2
- import { CrowdloanItem, CrowdloanParaState } from '@subwallet/extension-base/background/KoniTypes';
1
+ import { _ChainInfo, _CrowdloanFund } from '@subwallet/chain-list/types';
2
+ import { CrowdloanItem } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
4
- import { ApiPromise } from '@polkadot/api';
5
- export declare const subscribeAcalaContributeInterval: (polkadotAddresses: string[], paraState: CrowdloanParaState, callback: (rs: CrowdloanItem) => void) => () => void;
6
- export declare function getCrowdloanFundsStatus(api: ApiPromise): Promise<Record<string, CrowdloanParaState>>;
7
- export declare function subscribeCrowdloan(addresses: string[], substrateApiMap: Record<string, _SubstrateApi>, callback: (networkKey: string, rs: CrowdloanItem) => void, chainInfoMap: Record<string, _ChainInfo>): Promise<() => void>;
4
+ export declare type CrowdloanFundInfo = _CrowdloanFund & {
5
+ chain: string;
6
+ };
7
+ export declare const subscribeAcalaContributeInterval: (polkadotAddresses: string[], fundInfo: _CrowdloanFund, callback: (rs: CrowdloanItem) => void) => () => void;
8
+ export declare function subscribeCrowdloan(addresses: string[], substrateApiMap: Record<string, _SubstrateApi>, callback: (networkKey: string, rs: CrowdloanItem) => void, chainInfoMap: Record<string, _ChainInfo>): Promise<(() => void) | undefined>;
@@ -2,14 +2,34 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
5
+ import { _FundStatus } from '@subwallet/chain-list/types';
5
6
  import { APIItemState, CrowdloanParaState } from '@subwallet/extension-base/background/KoniTypes';
6
7
  import { ACALA_REFRESH_CROWDLOAN_INTERVAL } from '@subwallet/extension-base/constants';
7
8
  import registry from '@subwallet/extension-base/koni/api/dotsama/typeRegistry';
8
- import { _getChainSubstrateAddressPrefix, _getSubstrateParaId, _getSubstrateRelayParent, _isChainEvmCompatible, _isSubstrateParaChain } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import { categoryAddresses, reformatAddress } from '@subwallet/extension-base/utils';
10
10
  import axios from 'axios';
11
11
  import { BN } from '@polkadot/util';
12
- function getRPCCrowdloan(parentAPI, paraId, hexAddresses, paraState, callback) {
12
+ const STATUS_MAP = {
13
+ [_FundStatus.IN_AUCTION]: CrowdloanParaState.ONGOING,
14
+ [_FundStatus.WITHDRAW]: CrowdloanParaState.FAILED,
15
+ [_FundStatus.FAILED]: CrowdloanParaState.FAILED,
16
+ [_FundStatus.WON]: CrowdloanParaState.COMPLETED
17
+ };
18
+ const getOnlineFundList = (async () => {
19
+ const request = await axios.get('https://static-data.subwallet.app/crowdloan-funds/list.json');
20
+ return request.data;
21
+ })();
22
+ function getRPCCrowdloan(parentAPI, fundInfo, hexAddresses, callback) {
23
+ const {
24
+ auctionIndex,
25
+ endTime,
26
+ firstPeriod,
27
+ fundId,
28
+ lastPeriod,
29
+ paraId,
30
+ startTime,
31
+ status
32
+ } = fundInfo;
13
33
  const unsubPromise = parentAPI.api.derive.crowdloan.ownContributions(paraId, hexAddresses, result => {
14
34
  let contribute = new BN(0);
15
35
  Object.values(result).forEach(item => {
@@ -17,8 +37,16 @@ function getRPCCrowdloan(parentAPI, paraId, hexAddresses, paraState, callback) {
17
37
  });
18
38
  const rs = {
19
39
  state: APIItemState.READY,
20
- paraState,
21
- contribute: contribute.toString()
40
+ paraState: STATUS_MAP[fundInfo.status],
41
+ contribute: contribute.toString(),
42
+ fundId,
43
+ paraId,
44
+ status,
45
+ startTime,
46
+ endTime,
47
+ auctionIndex,
48
+ firstPeriod,
49
+ lastPeriod
22
50
  };
23
51
  callback(rs);
24
52
  });
@@ -28,7 +56,18 @@ function getRPCCrowdloan(parentAPI, paraId, hexAddresses, paraState, callback) {
28
56
  }).catch(console.error);
29
57
  };
30
58
  }
31
- export const subscribeAcalaContributeInterval = (polkadotAddresses, paraState, callback) => {
59
+ export const subscribeAcalaContributeInterval = (polkadotAddresses, fundInfo, callback) => {
60
+ const {
61
+ auctionIndex,
62
+ endTime,
63
+ firstPeriod,
64
+ fundId,
65
+ lastPeriod,
66
+ paraId,
67
+ startTime,
68
+ status
69
+ } = fundInfo;
70
+ const paraState = STATUS_MAP[fundInfo.status];
32
71
  const acalaContributionApi = 'https://api.polkawallet.io/acala-distribution-v2/crowdloan?account=';
33
72
  const getContributeInfo = () => {
34
73
  Promise.all(polkadotAddresses.map(polkadotAddress => {
@@ -37,14 +76,21 @@ export const subscribeAcalaContributeInterval = (polkadotAddresses, paraState, c
37
76
  let contribute = new BN(0);
38
77
  resList.forEach(res => {
39
78
  var _res$data$data, _res$data$data$acala, _res$data$data$acala$;
40
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument
79
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-member-access
41
80
  contribute = contribute.add(new BN(((_res$data$data = res.data.data) === null || _res$data$data === void 0 ? void 0 : (_res$data$data$acala = _res$data$data.acala) === null || _res$data$data$acala === void 0 ? void 0 : (_res$data$data$acala$ = _res$data$data$acala[0]) === null || _res$data$data$acala$ === void 0 ? void 0 : _res$data$data$acala$.totalDOTLocked) || '0'));
42
81
  });
43
82
  const rs = {
44
83
  state: APIItemState.READY,
45
84
  paraState,
46
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
47
- contribute: contribute.toString()
85
+ contribute: contribute.toString(),
86
+ fundId,
87
+ paraId,
88
+ status,
89
+ startTime,
90
+ endTime,
91
+ auctionIndex,
92
+ firstPeriod,
93
+ lastPeriod
48
94
  };
49
95
  callback(rs);
50
96
  }).catch(console.error);
@@ -55,64 +101,70 @@ export const subscribeAcalaContributeInterval = (polkadotAddresses, paraState, c
55
101
  clearInterval(interval);
56
102
  };
57
103
  };
58
- export async function getCrowdloanFundsStatus(api) {
59
- const leases = await api.query.slots.leases.keys();
60
- const leasesParaIds = leases.map(({
61
- args: [paraId]
62
- }) => paraId.toString());
63
- const rs = await api.query.crowdloan.funds.entries();
64
- const newRaise = await api.query.crowdloan.newRaise();
65
- const newRaiseParaIds = newRaise.toJSON().map(p => p.toString());
66
- return rs.reduce((stateMap, [{
67
- args: [paraId]
68
- }, fundData]) => {
69
- const paraStr = paraId.toString();
70
104
 
71
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
72
- // const item = fundData.unwrap() as PolkadotRuntimeCommonCrowdloanFundInfo;
105
+ // export async function getCrowdloanFundsStatus (api: ApiPromise) {
106
+ // const leases = await api.query.slots.leases.keys<ParaId[]>();
107
+ // const leasesParaIds = leases.map(({ args: [paraId] }) => paraId.toString());
73
108
 
74
- if (leasesParaIds.indexOf(paraStr) > -1) {
75
- stateMap[paraStr] = CrowdloanParaState.COMPLETED;
76
- }
77
- if (newRaiseParaIds.indexOf(paraStr) > -1) {
78
- stateMap[paraStr] = CrowdloanParaState.ONGOING;
79
- }
80
- return stateMap;
81
- }, {});
82
- }
109
+ // const rs = await api.query.crowdloan.funds.entries<Option<any>, ParaId[]>();
110
+ // const newRaise = await api.query.crowdloan.newRaise<Vec<u32>>();
111
+
112
+ // const newRaiseParaIds = (newRaise.toJSON() as number[]).map((p) => p.toString());
113
+
114
+ // return rs.reduce((stateMap, [{ args: [paraId] }, fundData]) => {
115
+ // const paraStr = paraId.toString();
116
+ // // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
117
+ // // const item = fundData.unwrap() as PolkadotRuntimeCommonCrowdloanFundInfo;
118
+ // if (leasesParaIds.indexOf(paraStr) > -1) {
119
+ // stateMap[paraStr] = CrowdloanParaState.COMPLETED;
120
+ // }
121
+ // if (newRaiseParaIds.indexOf(paraStr) > -1) {
122
+ // stateMap[paraStr] = CrowdloanParaState.ONGOING;
123
+ // }
124
+ // return stateMap;
125
+ // }, {} as Record<string, CrowdloanParaState>);
126
+ // }
83
127
 
84
128
  // Get All crowdloan
85
129
  export async function subscribeCrowdloan(addresses, substrateApiMap, callback, chainInfoMap) {
86
130
  const unsubMap = {};
131
+ const latestMap = {};
132
+ const rawFundList = await getOnlineFundList;
133
+ rawFundList.forEach(fundInfo => {
134
+ const chainSlug = fundInfo.chain;
135
+ if (!latestMap[chainSlug] || fundInfo.auctionIndex > latestMap[chainSlug].auctionIndex) {
136
+ latestMap[chainSlug] = fundInfo;
137
+ }
138
+ });
87
139
  if (Object.keys(substrateApiMap).includes(COMMON_CHAIN_SLUGS.KUSAMA) && Object.keys(substrateApiMap).includes(COMMON_CHAIN_SLUGS.POLKADOT)) {
140
+ const now = Date.now();
88
141
  const polkadotAPI = await substrateApiMap[COMMON_CHAIN_SLUGS.POLKADOT].isReady;
89
- const polkadotFundsStatusMap = await getCrowdloanFundsStatus(polkadotAPI.api);
90
142
  const kusamaAPI = await substrateApiMap[COMMON_CHAIN_SLUGS.KUSAMA].isReady;
91
- const kusamaFundsStatusMap = await getCrowdloanFundsStatus(kusamaAPI.api);
92
-
93
- // TODO: find all crowdloan valid networks: parachains, in-crowdloan, crowdloan but failed
94
-
95
143
  const substrateAddresses = categoryAddresses(addresses)[0];
96
144
  const hexAddresses = substrateAddresses.map(address => {
97
145
  return registry.createType('AccountId', address).toHex();
98
146
  });
99
- Object.entries(chainInfoMap).forEach(([networkKey, chainInfo]) => {
100
- if (_isSubstrateParaChain(chainInfo)) {
101
- const parentChain = _getSubstrateRelayParent(chainInfo);
147
+ if (addresses.length === 0) {
148
+ return;
149
+ }
150
+ Object.values(latestMap).forEach(fundInfo => {
151
+ var _chainInfoMap$chainSl;
152
+ const chainSlug = fundInfo.chain;
153
+ const endTime = new Date(fundInfo.endTime).getTime();
154
+ const parentChain = fundInfo.relayChain;
155
+ const substrateInfo = (_chainInfoMap$chainSl = chainInfoMap[chainSlug]) === null || _chainInfoMap$chainSl === void 0 ? void 0 : _chainInfoMap$chainSl.substrateInfo;
156
+ if (chainSlug && parentChain && STATUS_MAP[fundInfo.status] && fundInfo.paraId && endTime > now && substrateInfo) {
102
157
  const crowdloanCb = rs => {
103
- callback(networkKey, rs);
158
+ callback(chainSlug, rs);
104
159
  };
105
- const paraId = _getSubstrateParaId(chainInfo);
106
- if (paraId <= -1 || addresses.length === 0 || parentChain.length === 0) {
107
- return;
108
- }
109
- if (networkKey === COMMON_CHAIN_SLUGS.ACALA) {
110
- const acalaAddresses = substrateAddresses.map(address => reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo), _isChainEvmCompatible(chainInfo)));
111
- unsubMap.acala = subscribeAcalaContributeInterval(acalaAddresses, CrowdloanParaState.COMPLETED, crowdloanCb);
112
- } else if (parentChain === COMMON_CHAIN_SLUGS.POLKADOT && polkadotFundsStatusMap[paraId]) {
113
- unsubMap[networkKey] = getRPCCrowdloan(polkadotAPI, paraId, hexAddresses, polkadotFundsStatusMap[paraId], crowdloanCb);
114
- } else if (parentChain === COMMON_CHAIN_SLUGS.KUSAMA && kusamaFundsStatusMap[paraId]) {
115
- unsubMap[networkKey] = getRPCCrowdloan(kusamaAPI, paraId, hexAddresses, kusamaFundsStatusMap[paraId], crowdloanCb);
160
+ fundInfo.paraId = substrateInfo.crowdloanParaId || substrateInfo.paraId || fundInfo.paraId;
161
+ if (chainSlug === COMMON_CHAIN_SLUGS.ACALA) {
162
+ const acalaAddresses = substrateAddresses.map(address => reformatAddress(address, 10, false));
163
+ unsubMap.acala = subscribeAcalaContributeInterval(acalaAddresses, fundInfo, crowdloanCb);
164
+ } else if (parentChain === COMMON_CHAIN_SLUGS.POLKADOT) {
165
+ unsubMap[chainSlug] = getRPCCrowdloan(polkadotAPI, fundInfo, hexAddresses, crowdloanCb);
166
+ } else if (parentChain === COMMON_CHAIN_SLUGS.KUSAMA) {
167
+ unsubMap[chainSlug] = getRPCCrowdloan(kusamaAPI, fundInfo, hexAddresses, crowdloanCb);
116
168
  }
117
169
  }
118
170
  });
@@ -13,6 +13,7 @@ export declare const CF_IPFS_GATEWAY = "https://cf-ipfs.com/ipfs/";
13
13
  export declare const PINATA_IPFS_GATEWAY = "https://gateway.pinata.cloud/ipfs/";
14
14
  export declare const UNIQUE_SCAN_ENDPOINT = "https://explorer-api.unique.network/v1/graphql";
15
15
  export declare const QUARTZ_SCAN_ENDPOINT = "https://hasura-quartz.unique.network/v1/graphql";
16
+ export declare const VARA_SCAN_ENDPOINT = "https://nft-explorer.vara-network.io/graphql";
16
17
  export declare const UNIQUE_IPFS_GATEWAY = "https://ipfs.unique.network/ipfs/";
17
18
  export declare const NFT_STORAGE_GATEWAY = "https://nftstorage.link/ipfs/";
18
19
  export declare const IPFS_W3S_LINK = "https://w3s.link/ipfs/";
@@ -17,6 +17,10 @@ export const CF_IPFS_GATEWAY = 'https://cf-ipfs.com/ipfs/';
17
17
  export const PINATA_IPFS_GATEWAY = 'https://gateway.pinata.cloud/ipfs/';
18
18
  export const UNIQUE_SCAN_ENDPOINT = 'https://explorer-api.unique.network/v1/graphql';
19
19
  export const QUARTZ_SCAN_ENDPOINT = 'https://hasura-quartz.unique.network/v1/graphql';
20
+ export const VARA_SCAN_ENDPOINT = 'https://nft-explorer.vara-network.io/graphql';
21
+
22
+ // GATEWAY
23
+
20
24
  export const UNIQUE_IPFS_GATEWAY = 'https://ipfs.unique.network/ipfs/';
21
25
  export const NFT_STORAGE_GATEWAY = 'https://nftstorage.link/ipfs/';
22
26
  export const IPFS_W3S_LINK = 'https://w3s.link/ipfs/';
@@ -8,6 +8,7 @@ import { KaruraNftApi } from '@subwallet/extension-base/koni/api/nft/karura_nft'
8
8
  import { RmrkNftApi } from '@subwallet/extension-base/koni/api/nft/rmrk_nft';
9
9
  import StatemineNftApi from '@subwallet/extension-base/koni/api/nft/statemine_nft';
10
10
  import UniqueNftApi from '@subwallet/extension-base/koni/api/nft/unique_nft';
11
+ import { VaraNftApi } from '@subwallet/extension-base/koni/api/nft/vara_nft';
11
12
  import { WasmNftApi } from '@subwallet/extension-base/koni/api/nft/wasm_nft';
12
13
  import { _NFT_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
13
14
  import { _isChainSupportEvmNft, _isChainSupportNativeNft, _isChainSupportWasmNft } from '@subwallet/extension-base/services/chain-service/utils';
@@ -29,6 +30,8 @@ function createSubstrateNftApi(chain, substrateApi, addresses) {
29
30
  return new UniqueNftApi(substrateApi, substrateAddresses, chain);
30
31
  } else if (_NFT_CHAIN_GROUP.bitcountry.includes(chain)) {
31
32
  return new BitCountryNftApi(substrateApi, substrateAddresses, chain);
33
+ } else if (_NFT_CHAIN_GROUP.vara.includes(chain)) {
34
+ return new VaraNftApi(chain, substrateAddresses);
32
35
  }
33
36
  return null;
34
37
  }
@@ -0,0 +1,9 @@
1
+ import { BaseNftApi, HandleNftParams } from '@subwallet/extension-base/koni/api/nft/nft';
2
+ export declare class VaraNftApi extends BaseNftApi {
3
+ endpoint: string;
4
+ constructor(chain: string, addresses: string[]);
5
+ private static parseNftRequest;
6
+ private getNftByAccount;
7
+ handleNfts(params: HandleNftParams): Promise<void>;
8
+ fetchNfts(params: HandleNftParams): Promise<number>;
9
+ }
@@ -0,0 +1,99 @@
1
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { VARA_SCAN_ENDPOINT } from '@subwallet/extension-base/koni/api/nft/config';
5
+ import { BaseNftApi } from '@subwallet/extension-base/koni/api/nft/nft';
6
+ import fetch from 'cross-fetch';
7
+ import { hexAddPrefix, u8aToHex } from '@polkadot/util';
8
+ import { decodeAddress } from '@polkadot/util-crypto';
9
+ export class VaraNftApi extends BaseNftApi {
10
+ endpoint = VARA_SCAN_ENDPOINT;
11
+
12
+ // eslint-disable-next-line no-useless-constructor
13
+ constructor(chain, addresses) {
14
+ super(chain, undefined, addresses);
15
+ }
16
+ static parseNftRequest(publicKey) {
17
+ return {
18
+ // eslint-disable-next-line
19
+ query: `
20
+ query MyQuery {
21
+ accountById(id: "${publicKey}") {
22
+ id
23
+ nfts {
24
+ id
25
+ mediaUrl
26
+ name
27
+ tokenId
28
+ attribUrl
29
+ description
30
+ collection {
31
+ id
32
+ name
33
+ description
34
+ }
35
+ }
36
+ }
37
+ }
38
+ `
39
+ };
40
+ }
41
+
42
+ // private static parseNftCollectionRequest (collectionId: string) {
43
+ // return {
44
+ // // eslint-disable-next-line
45
+ // query: `query MyQuery { collections(where: {collection_id: {_eq: \"${collectionId}\"}}) { collection_id name } }`
46
+ // };
47
+ // }
48
+
49
+ async getNftByAccount(address) {
50
+ var _result$data, _result$data$accountB;
51
+ const publicKey = hexAddPrefix(u8aToHex(decodeAddress(address)));
52
+ const resp = await fetch(this.endpoint, {
53
+ method: 'post',
54
+ headers: {
55
+ 'Content-Type': 'application/json'
56
+ },
57
+ body: JSON.stringify(VaraNftApi.parseNftRequest(publicKey))
58
+ });
59
+ const result = await resp.json();
60
+
61
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
62
+ return result === null || result === void 0 ? void 0 : (_result$data = result.data) === null || _result$data === void 0 ? void 0 : (_result$data$accountB = _result$data.accountById) === null || _result$data$accountB === void 0 ? void 0 : _result$data$accountB.nfts;
63
+ }
64
+ async handleNfts(params) {
65
+ try {
66
+ await Promise.all(this.addresses.map(async address => {
67
+ const nfts = await this.getNftByAccount(address);
68
+ for (const nft of nfts) {
69
+ const parsedNft = {
70
+ id: nft.tokenId,
71
+ chain: this.chain,
72
+ owner: address,
73
+ name: nft.name,
74
+ image: this.parseUrl(nft.mediaUrl),
75
+ description: nft.description,
76
+ collectionId: nft.collection.id
77
+ };
78
+ const parsedCollection = {
79
+ collectionId: nft.collection.id,
80
+ chain: this.chain,
81
+ collectionName: nft.collection.name
82
+ };
83
+ params.updateItem(this.chain, parsedNft, address);
84
+ params.updateCollection(this.chain, parsedCollection);
85
+ }
86
+ }));
87
+ } catch (e) {
88
+ console.error(`Failed to fetch ${this.chain} nft`, e);
89
+ }
90
+ }
91
+ async fetchNfts(params) {
92
+ try {
93
+ await this.handleNfts(params);
94
+ } catch (e) {
95
+ return 0;
96
+ }
97
+ return 1;
98
+ }
99
+ }
@@ -213,5 +213,7 @@ export default class KoniExtension {
213
213
  private resolveAddressByDomain;
214
214
  private addInjects;
215
215
  private removeInjects;
216
+ private subscribeProcessingBanner;
217
+ private completeCampaignBanner;
216
218
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
217
219
  }
@@ -7,7 +7,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
7
7
  import { isJsonPayload, SEED_DEFAULT_LENGTH, SEED_LENGTHS } from '@subwallet/extension-base/background/handlers/Extension';
8
8
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
9
9
  import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
10
- import { AccountExternalErrorCode, BasicTxErrorType, BasicTxWarningCode, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, MantaPayEnableMessage, StakingType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
10
+ import { AccountExternalErrorCode, BasicTxErrorType, BasicTxWarningCode, CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, MantaPayEnableMessage, StakingType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
11
11
  import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
12
12
  import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
13
13
  import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
@@ -3512,6 +3512,46 @@ export default class KoniExtension {
3512
3512
  return true;
3513
3513
  }
3514
3514
 
3515
+ /* Campaign */
3516
+
3517
+ async subscribeProcessingBanner(id, port) {
3518
+ const cb = createSubscription(id, port);
3519
+ const filterBanner = data => {
3520
+ const result = [];
3521
+ for (const item of data) {
3522
+ if (item.type === CampaignDataType.BANNER) {
3523
+ result.push(item);
3524
+ }
3525
+ }
3526
+ return result;
3527
+ };
3528
+ const callback = data => {
3529
+ cb(filterBanner(data));
3530
+ };
3531
+ const subscription = this.#koniState.campaignService.subscribeProcessingCampaign().subscribe({
3532
+ next: callback
3533
+ });
3534
+ this.createUnsubscriptionHandle(id, subscription.unsubscribe);
3535
+ port.onDisconnect.addListener(() => {
3536
+ this.cancelSubscription(id);
3537
+ });
3538
+ return filterBanner(await this.#koniState.campaignService.getProcessingCampaign());
3539
+ }
3540
+ async completeCampaignBanner({
3541
+ slug
3542
+ }) {
3543
+ const campaign = await this.#koniState.dbService.getCampaign(slug);
3544
+ if (campaign) {
3545
+ await this.#koniState.dbService.upsertCampaign({
3546
+ ...campaign,
3547
+ isDone: true
3548
+ });
3549
+ }
3550
+ return true;
3551
+ }
3552
+
3553
+ /* Campaign */
3554
+
3515
3555
  // --------------------------------------------------------------
3516
3556
  // eslint-disable-next-line @typescript-eslint/require-await
3517
3557
  async handle(id, type, request, port) {
@@ -3948,6 +3988,13 @@ export default class KoniExtension {
3948
3988
  // Metadata
3949
3989
  case 'pri(metadata.find)':
3950
3990
  return this.findRawMetadata(request);
3991
+
3992
+ /* Campaign */
3993
+ case 'pri(campaign.banner.subscribe)':
3994
+ return this.subscribeProcessingBanner(id, port);
3995
+ case 'pri(campaign.banner.complete)':
3996
+ return this.completeCampaignBanner(request);
3997
+ /* Campaign */
3951
3998
  // Default
3952
3999
  default:
3953
4000
  throw new Error(`Unable to handle message of type ${type}`);
@@ -3,6 +3,7 @@ import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from
3
3
  import { AddTokenRequestExternal, AmountData, ApiMap, AuthRequestV2, BalanceItem, BalanceJson, ChainStakingMetadata, ConfirmationsQueue, CrowdloanItem, CrowdloanJson, CurrentAccountInfo, EvmSendTransactionParams, ExternalRequestPromise, MantaPayConfig, MantaPaySyncState, NftCollection, NftItem, NftJson, NominatorMetadata, RequestAccountExportPrivateKey, RequestCheckPublicAndSecretKey, RequestConfirmationComplete, RequestSettingsType, ResponseAccountExportPrivateKey, ResponseCheckPublicAndSecretKey, ServiceInfo, SingleModeJson, StakingItem, StakingJson, StakingRewardItem, StakingRewardJson, StakingType, UiSettings } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import { AccountJson, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestSign, ResponseRpcListProviders, ResponseSigning } from '@subwallet/extension-base/background/types';
5
5
  import { BalanceService } from '@subwallet/extension-base/services/balance-service';
6
+ import CampaignService from '@subwallet/extension-base/services/campaign-service';
6
7
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
7
8
  import { _ChainState, _NetworkUpsertParams, _ValidateCustomAssetRequest } from '@subwallet/extension-base/services/chain-service/types';
8
9
  import { EventService } from '@subwallet/extension-base/services/event-service';
@@ -62,6 +63,7 @@ export default class KoniState {
62
63
  readonly migrationService: MigrationService;
63
64
  readonly subscanService: SubscanService;
64
65
  readonly walletConnectService: WalletConnectService;
66
+ readonly campaignService: CampaignService;
65
67
  private generalStatus;
66
68
  private waitSleeping;
67
69
  private waitStarting;
@@ -1,7 +1,6 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { ChainInfoMap } from '@subwallet/chain-list';
5
4
  import { EvmProviderError } from '@subwallet/extension-base/background/errors/EvmProviderError';
6
5
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
7
6
  import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
@@ -9,9 +8,10 @@ import { APIItemState, BasicTxErrorType, ChainType, EvmProviderErrorType, Extern
9
8
  import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, MANTA_PAY_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
10
9
  import { BalanceService } from '@subwallet/extension-base/services/balance-service';
11
10
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
11
+ import CampaignService from '@subwallet/extension-base/services/campaign-service';
12
12
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
13
13
  import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _PREDEFINED_SINGLE_MODES } from '@subwallet/extension-base/services/chain-service/constants';
14
- import { _getEvmChainId, _getSubstrateGenesisHash, _getTokenOnChainAssetId, _isAssetFungibleToken, _isChainEnabled, _isChainTestNet, _isSubstrateParaChain, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils';
14
+ import { _getEvmChainId, _getSubstrateGenesisHash, _getTokenOnChainAssetId, _isAssetFungibleToken, _isChainEnabled, _isChainTestNet, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils';
15
15
  import { EventService } from '@subwallet/extension-base/services/event-service';
16
16
  import { HistoryService } from '@subwallet/extension-base/services/history-service';
17
17
  import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
@@ -51,14 +51,6 @@ const getSuri = (seed, type) => {
51
51
  };
52
52
  const generateDefaultCrowdloanMap = () => {
53
53
  const crowdloanMap = {};
54
- Object.entries(ChainInfoMap).forEach(([networkKey, chainInfo]) => {
55
- if (_isSubstrateParaChain(chainInfo)) {
56
- crowdloanMap[networkKey] = {
57
- state: APIItemState.PENDING,
58
- contribute: '0'
59
- };
60
- }
61
- });
62
54
  return crowdloanMap;
63
55
  };
64
56
  export default class KoniState {
@@ -101,7 +93,8 @@ export default class KoniState {
101
93
  this.historyService = new HistoryService(this.dbService, this.chainService, this.eventService, this.keyringService);
102
94
  this.transactionService = new TransactionService(this.chainService, this.eventService, this.requestService, this.balanceService, this.historyService, this.notificationService, this.dbService);
103
95
  this.walletConnectService = new WalletConnectService(this, this.requestService);
104
- this.migrationService = new MigrationService(this);
96
+ this.migrationService = new MigrationService(this, this.eventService);
97
+ this.campaignService = new CampaignService(this);
105
98
  this.subscription = new KoniSubscription(this, this.dbService);
106
99
  this.cron = new KoniCron(this, this.subscription, this.dbService);
107
100
  this.logger = createLogger('State');