@subwallet/extension-base 1.1.54-0 → 1.1.56-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 (112) hide show
  1. package/background/KoniTypes.d.ts +30 -2
  2. package/background/KoniTypes.js +6 -0
  3. package/background/errors/SwapError.d.ts +6 -0
  4. package/background/errors/SwapError.js +57 -0
  5. package/background/errors/TransactionError.js +9 -0
  6. package/background/types.d.ts +2 -0
  7. package/cjs/background/KoniTypes.js +8 -1
  8. package/cjs/background/errors/SwapError.js +64 -0
  9. package/cjs/background/errors/TransactionError.js +9 -0
  10. package/cjs/koni/api/nft/{statemint_nft → assethub_nft}/index.js +5 -3
  11. package/cjs/koni/api/nft/{statemine_nft → assethub_unique}/index.js +5 -3
  12. package/cjs/koni/api/nft/index.js +13 -13
  13. package/cjs/koni/api/nft/nft.js +1 -1
  14. package/cjs/koni/api/nft/transfer.js +11 -15
  15. package/cjs/koni/api/staking/bonding/utils.js +35 -6
  16. package/cjs/koni/background/handlers/Extension.js +214 -102
  17. package/cjs/koni/background/handlers/State.js +5 -2
  18. package/cjs/packageInfo.js +1 -1
  19. package/cjs/services/balance-service/index.js +6 -3
  20. package/cjs/services/chain-service/constants.js +18 -4
  21. package/cjs/services/chain-service/index.js +39 -18
  22. package/cjs/services/chain-service/utils/index.js +15 -4
  23. package/cjs/services/chain-service/utils/patch.js +1 -1
  24. package/cjs/services/earning-service/constants/chains.js +4 -2
  25. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +7 -9
  26. package/cjs/services/earning-service/handlers/native-staking/astar.js +4 -3
  27. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +11 -8
  28. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +22 -3
  29. package/cjs/services/earning-service/handlers/nomination-pool/index.js +19 -5
  30. package/cjs/services/earning-service/service.js +0 -1
  31. package/cjs/services/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +4 -17
  32. package/cjs/services/migration-service/scripts/databases/MigrateAssetSetting.js +4 -17
  33. package/cjs/services/migration-service/scripts/index.js +3 -3
  34. package/cjs/services/swap-service/handler/base-handler.js +189 -0
  35. package/cjs/services/swap-service/handler/chainflip-handler.js +407 -0
  36. package/cjs/services/swap-service/handler/hydradx-handler.js +531 -0
  37. package/cjs/services/swap-service/index.js +250 -0
  38. package/cjs/services/swap-service/utils.js +126 -0
  39. package/cjs/services/transaction-service/index.js +20 -0
  40. package/cjs/services/transaction-service/utils.js +6 -0
  41. package/cjs/types/fee/evm.js +1 -0
  42. package/cjs/types/fee/fee.js +70 -0
  43. package/cjs/types/fee/index.js +27 -1
  44. package/cjs/types/service-base.js +1 -0
  45. package/cjs/types/swap/index.js +50 -0
  46. package/cjs/utils/index.js +12 -0
  47. package/cjs/utils/swap.js +78 -0
  48. package/koni/api/nft/{statemint_nft → assethub_nft}/index.d.ts +1 -1
  49. package/koni/api/nft/{statemint_nft → assethub_nft}/index.js +4 -2
  50. package/koni/api/nft/{statemine_nft → assethub_unique}/index.d.ts +1 -1
  51. package/koni/api/nft/{statemine_nft → assethub_unique}/index.js +4 -2
  52. package/koni/api/nft/index.js +13 -13
  53. package/koni/api/nft/nft.js +1 -1
  54. package/koni/api/nft/transfer.d.ts +1 -2
  55. package/koni/api/nft/transfer.js +10 -13
  56. package/koni/api/staking/bonding/utils.d.ts +3 -1
  57. package/koni/api/staking/bonding/utils.js +32 -6
  58. package/koni/background/handlers/Extension.d.ts +6 -0
  59. package/koni/background/handlers/Extension.js +111 -0
  60. package/koni/background/handlers/State.d.ts +2 -0
  61. package/koni/background/handlers/State.js +5 -2
  62. package/package.json +85 -28
  63. package/packageInfo.js +1 -1
  64. package/services/balance-service/index.js +6 -3
  65. package/services/base/types.d.ts +4 -0
  66. package/services/chain-service/constants.js +18 -4
  67. package/services/chain-service/index.d.ts +4 -0
  68. package/services/chain-service/index.js +21 -1
  69. package/services/chain-service/utils/index.d.ts +7 -5
  70. package/services/chain-service/utils/index.js +9 -2
  71. package/services/chain-service/utils/patch.js +1 -1
  72. package/services/earning-service/constants/chains.d.ts +1 -0
  73. package/services/earning-service/constants/chains.js +1 -0
  74. package/services/earning-service/handlers/native-staking/amplitude.js +7 -9
  75. package/services/earning-service/handlers/native-staking/astar.js +4 -3
  76. package/services/earning-service/handlers/native-staking/para-chain.js +12 -9
  77. package/services/earning-service/handlers/native-staking/relay-chain.js +24 -5
  78. package/services/earning-service/handlers/nomination-pool/index.js +19 -5
  79. package/services/earning-service/service.js +0 -1
  80. package/services/event-service/types.d.ts +1 -0
  81. package/services/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +4 -17
  82. package/services/migration-service/scripts/databases/MigrateAssetSetting.js +4 -17
  83. package/services/migration-service/scripts/index.js +3 -3
  84. package/services/swap-service/handler/base-handler.d.ts +38 -0
  85. package/services/swap-service/handler/base-handler.js +180 -0
  86. package/services/swap-service/handler/chainflip-handler.d.ts +30 -0
  87. package/services/swap-service/handler/chainflip-handler.js +399 -0
  88. package/services/swap-service/handler/hydradx-handler.d.ts +36 -0
  89. package/services/swap-service/handler/hydradx-handler.js +522 -0
  90. package/services/swap-service/index.d.ts +32 -0
  91. package/services/swap-service/index.js +241 -0
  92. package/services/swap-service/utils.d.ts +18 -0
  93. package/services/swap-service/utils.js +105 -0
  94. package/services/transaction-service/index.js +20 -0
  95. package/services/transaction-service/utils.d.ts +2 -0
  96. package/services/transaction-service/utils.js +6 -2
  97. package/types/fee/evm.d.ts +49 -0
  98. package/types/fee/evm.js +1 -0
  99. package/types/fee/fee.d.ts +32 -0
  100. package/types/fee/fee.js +63 -0
  101. package/types/fee/index.d.ts +2 -49
  102. package/types/fee/index.js +5 -1
  103. package/types/service-base.d.ts +10 -0
  104. package/types/service-base.js +1 -0
  105. package/types/swap/index.d.ts +168 -0
  106. package/types/swap/index.js +41 -0
  107. package/types/yield/info/chain/target.d.ts +2 -0
  108. package/types/yield/info/pallet.d.ts +8 -0
  109. package/utils/index.d.ts +1 -0
  110. package/utils/index.js +2 -1
  111. package/utils/swap.d.ts +3 -0
  112. package/utils/swap.js +70 -0
@@ -0,0 +1,241 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
+ import { BasicTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
7
+ import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
8
+ import { ChainflipSwapHandler } from '@subwallet/extension-base/services/swap-service/handler/chainflip-handler';
9
+ import { HydradxHandler } from '@subwallet/extension-base/services/swap-service/handler/hydradx-handler';
10
+ import { DEFAULT_SWAP_FIRST_STEP, getSwapAltToken, MOCK_SWAP_FEE, SWAP_QUOTE_TIMEOUT_MAP } from '@subwallet/extension-base/services/swap-service/utils';
11
+ import { _SUPPORTED_SWAP_PROVIDERS, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
12
+ import { createPromiseHandler } from '@subwallet/extension-base/utils';
13
+ import { BehaviorSubject } from 'rxjs';
14
+ export class SwapService {
15
+ swapPairSubject = new BehaviorSubject([]);
16
+ handlers = {};
17
+ startPromiseHandler = createPromiseHandler();
18
+ stopPromiseHandler = createPromiseHandler();
19
+ status = ServiceStatus.NOT_INITIALIZED;
20
+ constructor(state) {
21
+ this.state = state;
22
+ this.eventService = state.eventService;
23
+ this.chainService = state.chainService;
24
+ }
25
+ async askProvidersForQuote(request) {
26
+ const availableQuotes = [];
27
+ await Promise.all(Object.values(this.handlers).map(async handler => {
28
+ if (handler.init && handler.isReady === false) {
29
+ await handler.init();
30
+ }
31
+ const quote = await handler.getSwapQuote(request);
32
+ if (!(quote instanceof SwapError)) {
33
+ availableQuotes.push({
34
+ quote
35
+ });
36
+ } else {
37
+ availableQuotes.push({
38
+ error: quote
39
+ });
40
+ }
41
+ }));
42
+ return availableQuotes; // todo: need to propagate error for further handling
43
+ }
44
+
45
+ getDefaultProcess(params) {
46
+ const result = {
47
+ totalFee: [MOCK_SWAP_FEE],
48
+ steps: [DEFAULT_SWAP_FIRST_STEP]
49
+ };
50
+ result.totalFee.push({
51
+ feeComponent: [],
52
+ feeOptions: [params.request.pair.from],
53
+ defaultFeeToken: params.request.pair.from
54
+ });
55
+ result.steps.push({
56
+ id: result.steps.length,
57
+ name: 'Swap',
58
+ type: SwapStepType.SWAP
59
+ });
60
+ return result;
61
+ }
62
+ async generateOptimalProcess(params) {
63
+ if (!params.selectedQuote) {
64
+ return this.getDefaultProcess(params);
65
+ } else {
66
+ const providerId = params.selectedQuote.provider.id;
67
+ const handler = this.handlers[providerId];
68
+ if (handler) {
69
+ return handler.generateOptimalProcess(params);
70
+ } else {
71
+ return this.getDefaultProcess(params);
72
+ }
73
+ }
74
+ }
75
+ async handleSwapRequest(request) {
76
+ /*
77
+ * 1. Ask swap quotes from providers
78
+ * 2. Select the best quote
79
+ * 3. Generate optimal process for that quote
80
+ * */
81
+
82
+ const swapQuoteResponse = await this.getLatestQuotes(request);
83
+ const optimalProcess = await this.generateOptimalProcess({
84
+ request,
85
+ selectedQuote: swapQuoteResponse.optimalQuote
86
+ });
87
+ console.log('optimalProcess', optimalProcess);
88
+ return {
89
+ process: optimalProcess,
90
+ quote: swapQuoteResponse
91
+ };
92
+ }
93
+ async getLatestQuotes(request) {
94
+ request.pair.metadata = this.getSwapPairMetadata(request.pair.slug); // todo: improve this
95
+ const quoteAskResponses = await this.askProvidersForQuote(request);
96
+
97
+ // todo: handle error to return back to UI
98
+ // todo: more logic to select the best quote
99
+
100
+ const availableQuotes = quoteAskResponses.filter(quote => !quote.error).map(quote => quote.quote);
101
+ let quoteError;
102
+ let selectedQuote;
103
+ let aliveUntil = +Date.now() + SWAP_QUOTE_TIMEOUT_MAP.default;
104
+ if (availableQuotes.length === 0) {
105
+ const preferredErrorResp = quoteAskResponses.find(quote => {
106
+ return !!quote.error && ![SwapErrorType.UNKNOWN, SwapErrorType.ASSET_NOT_SUPPORTED].includes(quote.error.errorType);
107
+ });
108
+ const defaultErrorResp = quoteAskResponses.find(quote => !!quote.error);
109
+ quoteError = (preferredErrorResp === null || preferredErrorResp === void 0 ? void 0 : preferredErrorResp.error) || (defaultErrorResp === null || defaultErrorResp === void 0 ? void 0 : defaultErrorResp.error);
110
+ } else {
111
+ var _selectedQuote;
112
+ selectedQuote = availableQuotes[0];
113
+ aliveUntil = ((_selectedQuote = selectedQuote) === null || _selectedQuote === void 0 ? void 0 : _selectedQuote.aliveUntil) || +Date.now() + SWAP_QUOTE_TIMEOUT_MAP.default;
114
+ }
115
+ return {
116
+ optimalQuote: selectedQuote,
117
+ quotes: availableQuotes,
118
+ error: quoteError,
119
+ aliveUntil
120
+ };
121
+ }
122
+ initHandlers() {
123
+ _SUPPORTED_SWAP_PROVIDERS.forEach(providerId => {
124
+ switch (providerId) {
125
+ case SwapProviderId.CHAIN_FLIP_TESTNET:
126
+ this.handlers[providerId] = new ChainflipSwapHandler(this.chainService, this.state.balanceService);
127
+ break;
128
+ case SwapProviderId.CHAIN_FLIP_MAINNET:
129
+ this.handlers[providerId] = new ChainflipSwapHandler(this.chainService, this.state.balanceService, false);
130
+ break;
131
+ case SwapProviderId.HYDRADX_TESTNET:
132
+ this.handlers[providerId] = new HydradxHandler(this.chainService, this.state.balanceService);
133
+ break;
134
+ case SwapProviderId.HYDRADX_MAINNET:
135
+ this.handlers[providerId] = new HydradxHandler(this.chainService, this.state.balanceService, false);
136
+ break;
137
+ default:
138
+ throw new Error('Unsupported provider');
139
+ }
140
+ });
141
+ }
142
+ async init() {
143
+ this.status = ServiceStatus.INITIALIZING;
144
+ this.eventService.emit('swap.ready', true);
145
+ this.status = ServiceStatus.INITIALIZED;
146
+ this.initHandlers();
147
+ await this.start();
148
+ }
149
+ async start() {
150
+ if (this.status === ServiceStatus.STOPPING) {
151
+ await this.waitForStopped();
152
+ }
153
+ if (this.status === ServiceStatus.STARTED || this.status === ServiceStatus.STARTING) {
154
+ return this.waitForStarted();
155
+ }
156
+ this.status = ServiceStatus.STARTING;
157
+
158
+ // todo: start the service jobs, subscribe data,...
159
+
160
+ this.swapPairSubject.next(this.getSwapPairs()); // todo: might need to change it online
161
+
162
+ // Update promise handler
163
+ this.startPromiseHandler.resolve();
164
+ this.stopPromiseHandler = createPromiseHandler();
165
+ this.status = ServiceStatus.STARTED;
166
+ }
167
+ async stop() {
168
+ if (this.status === ServiceStatus.STARTING) {
169
+ await this.waitForStarted();
170
+ }
171
+ if (this.status === ServiceStatus.STOPPED || this.status === ServiceStatus.STOPPING) {
172
+ return this.waitForStopped();
173
+ }
174
+
175
+ // todo: unsub, persist data,...
176
+
177
+ this.stopPromiseHandler.resolve();
178
+ this.startPromiseHandler = createPromiseHandler();
179
+ this.status = ServiceStatus.STOPPED;
180
+ }
181
+ waitForStarted() {
182
+ return this.startPromiseHandler.promise;
183
+ }
184
+ waitForStopped() {
185
+ return this.stopPromiseHandler.promise;
186
+ }
187
+ getSwapPairs() {
188
+ return Object.entries(this.chainService.swapRefMap).map(([slug, assetRef]) => {
189
+ const fromAsset = this.chainService.getAssetBySlug(assetRef.srcAsset);
190
+ return {
191
+ slug,
192
+ from: assetRef.srcAsset,
193
+ to: assetRef.destAsset,
194
+ metadata: {
195
+ alternativeAsset: getSwapAltToken(fromAsset)
196
+ }
197
+ };
198
+ });
199
+ }
200
+ getSwapPairMetadata(slug) {
201
+ var _this$getSwapPairs$fi;
202
+ return (_this$getSwapPairs$fi = this.getSwapPairs().find(pair => pair.slug === slug)) === null || _this$getSwapPairs$fi === void 0 ? void 0 : _this$getSwapPairs$fi.metadata;
203
+ }
204
+ async validateSwapProcess(params) {
205
+ const providerId = params.selectedQuote.provider.id;
206
+ const handler = this.handlers[providerId];
207
+ if (handler) {
208
+ return handler.validateSwapProcess(params);
209
+ } else {
210
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
211
+ }
212
+ }
213
+ async handleSwapProcess(params) {
214
+ const handler = this.handlers[params.quote.provider.id];
215
+ if (params.process.steps.length === 1) {
216
+ // todo: do better to handle error generating steps
217
+ return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Please check your network and try again'));
218
+ }
219
+ if (handler) {
220
+ return handler.handleSwapProcess(params);
221
+ } else {
222
+ return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
223
+ }
224
+ }
225
+ subscribeSwapPairs(callback) {
226
+ return this.chainService.subscribeSwapRefMap().subscribe(refMap => {
227
+ const latestData = Object.entries(refMap).map(([slug, assetRef]) => {
228
+ const fromAsset = this.chainService.getAssetBySlug(assetRef.srcAsset);
229
+ return {
230
+ slug,
231
+ from: assetRef.srcAsset,
232
+ to: assetRef.destAsset,
233
+ metadata: {
234
+ alternativeAsset: getSwapAltToken(fromAsset)
235
+ }
236
+ };
237
+ });
238
+ callback(latestData);
239
+ });
240
+ }
241
+ }
@@ -0,0 +1,18 @@
1
+ import { Asset, Chain } from '@chainflip/sdk/swap';
2
+ import { _ChainAsset } from '@subwallet/chain-list/types';
3
+ import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
4
+ import { ChainflipPreValidationMetadata, HydradxPreValidationMetadata, SwapErrorType, SwapFeeInfo, SwapPair, SwapStepDetail } from '@subwallet/extension-base/types/swap';
5
+ export declare const CHAIN_FLIP_TESTNET_EXPLORER = "https://blocks-perseverance.chainflip.io";
6
+ export declare const CHAIN_FLIP_MAINNET_EXPLORER = "https://scan.chainflip.io";
7
+ export declare const CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING: Record<string, Chain>;
8
+ export declare const CHAIN_FLIP_SUPPORTED_TESTNET_MAPPING: Record<string, Chain>;
9
+ export declare const CHAIN_FLIP_SUPPORTED_MAINNET_ASSET_MAPPING: Record<string, Asset>;
10
+ export declare const CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING: Record<string, Asset>;
11
+ export declare const SWAP_QUOTE_TIMEOUT_MAP: Record<string, number>;
12
+ export declare const DEFAULT_SWAP_FIRST_STEP: SwapStepDetail;
13
+ export declare const MOCK_SWAP_FEE: SwapFeeInfo;
14
+ export declare function getSwapAlternativeAsset(swapPair: SwapPair): string | undefined;
15
+ export declare function getSwapAltToken(chainAsset: _ChainAsset): string | undefined;
16
+ export declare function calculateSwapRate(fromAmount: string, toAmount: string, fromAsset: _ChainAsset, toAsset: _ChainAsset): number;
17
+ export declare function getChainflipEarlyValidationError(error: SwapErrorType, metadata: ChainflipPreValidationMetadata): SwapError;
18
+ export declare function getEarlyHydradxValidationError(error: SwapErrorType, metadata: HydradxPreValidationMetadata): SwapError;
@@ -0,0 +1,105 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Assets, Chains } from '@chainflip/sdk/swap';
5
+ import { COMMON_ASSETS, COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
6
+ import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
7
+ import { _getAssetDecimals } from '@subwallet/extension-base/services/chain-service/utils';
8
+ import { SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
9
+ import { formatNumber } from '@subwallet/extension-base/utils';
10
+ import BigN from 'bignumber.js';
11
+ export const CHAIN_FLIP_TESTNET_EXPLORER = 'https://blocks-perseverance.chainflip.io';
12
+ export const CHAIN_FLIP_MAINNET_EXPLORER = 'https://scan.chainflip.io';
13
+ export const CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING = {
14
+ [COMMON_CHAIN_SLUGS.POLKADOT]: Chains.Polkadot,
15
+ [COMMON_CHAIN_SLUGS.ETHEREUM]: Chains.Ethereum
16
+ };
17
+ export const CHAIN_FLIP_SUPPORTED_TESTNET_MAPPING = {
18
+ [COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA]: Chains.Ethereum,
19
+ [COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT]: Chains.Polkadot
20
+ };
21
+ export const CHAIN_FLIP_SUPPORTED_MAINNET_ASSET_MAPPING = {
22
+ [COMMON_ASSETS.DOT]: Assets.DOT,
23
+ [COMMON_ASSETS.ETH]: Assets.ETH,
24
+ [COMMON_ASSETS.USDC_ETHEREUM]: Assets.USDC
25
+ };
26
+ export const CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = {
27
+ [COMMON_ASSETS.PDOT]: Assets.DOT,
28
+ [COMMON_ASSETS.ETH_SEPOLIA]: Assets.ETH,
29
+ [COMMON_ASSETS.USDC_SEPOLIA]: Assets.USDC
30
+ };
31
+ export const SWAP_QUOTE_TIMEOUT_MAP = {
32
+ // in milliseconds
33
+ default: 30000,
34
+ [SwapProviderId.CHAIN_FLIP_TESTNET]: 30000,
35
+ [SwapProviderId.CHAIN_FLIP_MAINNET]: 30000
36
+ };
37
+ export const DEFAULT_SWAP_FIRST_STEP = {
38
+ id: 0,
39
+ name: 'Fill information',
40
+ type: SwapStepType.DEFAULT
41
+ };
42
+ export const MOCK_SWAP_FEE = {
43
+ feeComponent: [],
44
+ defaultFeeToken: '',
45
+ feeOptions: []
46
+ };
47
+ export function getSwapAlternativeAsset(swapPair) {
48
+ var _swapPair$metadata;
49
+ return swapPair === null || swapPair === void 0 ? void 0 : (_swapPair$metadata = swapPair.metadata) === null || _swapPair$metadata === void 0 ? void 0 : _swapPair$metadata.alternativeAsset;
50
+ }
51
+ export function getSwapAltToken(chainAsset) {
52
+ var _chainAsset$metadata;
53
+ return (_chainAsset$metadata = chainAsset.metadata) === null || _chainAsset$metadata === void 0 ? void 0 : _chainAsset$metadata.alternativeSwapAsset;
54
+ }
55
+ export function calculateSwapRate(fromAmount, toAmount, fromAsset, toAsset) {
56
+ const bnFromAmount = new BigN(fromAmount);
57
+ const bnToAmount = new BigN(toAmount);
58
+ const decimalDiff = _getAssetDecimals(toAsset) - _getAssetDecimals(fromAsset);
59
+ const bnRate = bnFromAmount.div(bnToAmount);
60
+ return 1 / bnRate.times(10 ** decimalDiff).toNumber();
61
+ }
62
+ export function getChainflipEarlyValidationError(error, metadata) {
63
+ // todo: support more providers
64
+ switch (error) {
65
+ case SwapErrorType.NOT_MEET_MIN_SWAP:
66
+ {
67
+ const parsedMinSwapValue = formatNumber(metadata.minSwap.value, metadata.minSwap.decimals);
68
+ const message = `Amount too low. Increase your amount above ${parsedMinSwapValue} ${metadata.minSwap.symbol} and try again`;
69
+ return new SwapError(error, message);
70
+ }
71
+ case SwapErrorType.SWAP_EXCEED_ALLOWANCE:
72
+ {
73
+ if (metadata.maxSwap) {
74
+ const parsedMaxSwapValue = formatNumber(metadata.maxSwap.value, metadata.maxSwap.decimals);
75
+ return new SwapError(error, `Amount too high. Lower your amount below ${parsedMaxSwapValue} ${metadata.maxSwap.symbol} and try again`);
76
+ } else {
77
+ return new SwapError(error, 'Amount too high. Lower your amount and try again');
78
+ }
79
+ }
80
+ case SwapErrorType.ASSET_NOT_SUPPORTED:
81
+ return new SwapError(error, 'This swap pair is not supported');
82
+ case SwapErrorType.UNKNOWN:
83
+ return new SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
84
+ case SwapErrorType.ERROR_FETCHING_QUOTE:
85
+ return new SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
86
+ default:
87
+ return new SwapError(error);
88
+ }
89
+ }
90
+ export function getEarlyHydradxValidationError(error, metadata) {
91
+ switch (error) {
92
+ case SwapErrorType.AMOUNT_CANNOT_BE_ZERO:
93
+ {
94
+ return new SwapError(error, 'Amount too low. Increase your amount above 0 and try again');
95
+ }
96
+ case SwapErrorType.ASSET_NOT_SUPPORTED:
97
+ return new SwapError(error, 'This swap pair is not supported');
98
+ case SwapErrorType.UNKNOWN:
99
+ return new SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
100
+ case SwapErrorType.ERROR_FETCHING_QUOTE:
101
+ return new SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
102
+ default:
103
+ return new SwapError(error);
104
+ }
105
+ }
@@ -639,6 +639,18 @@ export default class TransactionService {
639
639
  };
640
640
  break;
641
641
  }
642
+ case ExtrinsicType.SWAP:
643
+ {
644
+ const data = parseTransactionData(transaction.data); // TODO: switch by provider
645
+ const inputAsset = this.state.chainService.getAssetBySlug(data.quote.pair.from);
646
+ historyItem.amount = {
647
+ value: data.quote.fromAmount,
648
+ symbol: _getAssetSymbol(inputAsset),
649
+ decimals: _getAssetDecimals(inputAsset)
650
+ };
651
+ historyItem.additionalInfo = data;
652
+ break;
653
+ }
642
654
  case ExtrinsicType.UNKNOWN:
643
655
  break;
644
656
  }
@@ -732,6 +744,14 @@ export default class TransactionService {
732
744
  }
733
745
  } else if ([ExtrinsicType.STAKING_BOND, ExtrinsicType.STAKING_UNBOND, ExtrinsicType.STAKING_WITHDRAW, ExtrinsicType.STAKING_CANCEL_UNSTAKE, ExtrinsicType.STAKING_CLAIM_REWARD, ExtrinsicType.STAKING_JOIN_POOL, ExtrinsicType.STAKING_POOL_WITHDRAW, ExtrinsicType.STAKING_LEAVE_POOL].includes(transaction.extrinsicType)) {
734
746
  this.state.eventService.emit('transaction.submitStaking', transaction.chain);
747
+ } else if (transaction.extrinsicType === ExtrinsicType.SWAP) {
748
+ const inputData = parseTransactionData(transaction.data);
749
+ const toAssetSlug = inputData.quote.pair.to;
750
+
751
+ // todo: consider async
752
+ this.state.chainService.updateAssetSetting(toAssetSlug, {
753
+ visible: true
754
+ }, true).catch(console.error);
735
755
  }
736
756
  }
737
757
  onSuccess({
@@ -1,4 +1,6 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ExtrinsicDataTypeMap, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { ChainflipSwapTxData } from '@subwallet/extension-base/types/swap';
3
4
  export declare function parseTransactionData<T extends ExtrinsicType>(data: unknown): ExtrinsicDataTypeMap[T];
4
5
  export declare function getExplorerLink(chainInfo: _ChainInfo, value: string, type: 'account' | 'tx'): string | undefined;
6
+ export declare function getChainflipExplorerLink(data: ChainflipSwapTxData, chainInfo: _ChainInfo): string;
@@ -1,8 +1,8 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { _getBlockExplorerFromChain, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
5
-
4
+ import { _getBlockExplorerFromChain, _isChainTestNet, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
5
+ import { CHAIN_FLIP_MAINNET_EXPLORER, CHAIN_FLIP_TESTNET_EXPLORER } from '@subwallet/extension-base/services/swap-service/utils';
6
6
  // @ts-ignore
7
7
  export function parseTransactionData(data) {
8
8
  // @ts-ignore
@@ -47,4 +47,8 @@ export function getExplorerLink(chainInfo, value, type) {
47
47
  return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}${route}/${value}`;
48
48
  }
49
49
  return undefined;
50
+ }
51
+ export function getChainflipExplorerLink(data, chainInfo) {
52
+ const chainflipDomain = _isChainTestNet(chainInfo) ? CHAIN_FLIP_TESTNET_EXPLORER : CHAIN_FLIP_MAINNET_EXPLORER;
53
+ return `${chainflipDomain}/channels/${data.depositChannelId}`;
50
54
  }
@@ -0,0 +1,49 @@
1
+ import BigN from 'bignumber.js';
2
+ interface BaseFeeInfo {
3
+ busyNetwork: boolean;
4
+ }
5
+ export interface EvmLegacyFeeInfo extends BaseFeeInfo {
6
+ gasPrice: string;
7
+ maxFeePerGas: undefined;
8
+ maxPriorityFeePerGas: undefined;
9
+ baseGasFee: undefined;
10
+ }
11
+ export interface EvmEIP1995FeeInfo extends BaseFeeInfo {
12
+ gasPrice: undefined;
13
+ maxFeePerGas: BigN;
14
+ maxPriorityFeePerGas: BigN;
15
+ baseGasFee: BigN;
16
+ }
17
+ export declare type EvmFeeInfo = EvmLegacyFeeInfo | EvmEIP1995FeeInfo;
18
+ export interface EvmLegacyFeeInfoCache extends BaseFeeInfo {
19
+ gasPrice: string;
20
+ maxFeePerGas: undefined;
21
+ maxPriorityFeePerGas: undefined;
22
+ baseGasFee: undefined;
23
+ }
24
+ export interface EvmEIP1995FeeInfoCache extends BaseFeeInfo {
25
+ gasPrice: undefined;
26
+ maxFeePerGas: string;
27
+ maxPriorityFeePerGas: string;
28
+ baseGasFee: string;
29
+ }
30
+ export declare type EvmFeeInfoCache = EvmLegacyFeeInfoCache | EvmEIP1995FeeInfoCache;
31
+ export interface InfuraFeeDetail {
32
+ suggestedMaxPriorityFeePerGas: string;
33
+ suggestedMaxFeePerGas: string;
34
+ minWaitTimeEstimate: number;
35
+ maxWaitTimeEstimate: number;
36
+ }
37
+ export interface InfuraFeeInfo {
38
+ low: InfuraFeeDetail;
39
+ medium: InfuraFeeDetail;
40
+ high: InfuraFeeDetail;
41
+ networkCongestion: number;
42
+ estimatedBaseFee: string;
43
+ latestPriorityFeeRange: [string, string];
44
+ historicalPriorityFeeRange: [string, string];
45
+ historicalBaseFeeRange: [string, string];
46
+ priorityFeeTrend: 'down' | 'up';
47
+ baseFeeTrend: 'down' | 'up';
48
+ }
49
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { _ChainAsset } from '@subwallet/chain-list/types';
2
+ export declare enum SWFeeType {
3
+ EIP_1559 = "EIP_1559",
4
+ LEGACY = "LEGACY",
5
+ SUBSTRATE = "SUBSTRATE"
6
+ }
7
+ export interface FeeOption {
8
+ tokenInfo: _ChainAsset;
9
+ isDefault: boolean;
10
+ amount?: string;
11
+ type: SWFeeType;
12
+ metadata?: any;
13
+ }
14
+ export interface MultiFee {
15
+ feeOptions: FeeOption[];
16
+ totalFeeValue?: number;
17
+ }
18
+ export declare class SWFee {
19
+ chain: string;
20
+ feeOptions: FeeOption[];
21
+ private _selectedFeeOption?;
22
+ private _transactionId?;
23
+ get transactionId(): string | undefined;
24
+ get selectedFeeOption(): FeeOption | undefined;
25
+ static build(feeOptions: FeeOption[], chain: string, selectedFeeOption?: FeeOption): SWFee;
26
+ static buildSimpleFee(tokenInfo: _ChainAsset, amount: string, type: SWFeeType): SWFee;
27
+ static buildFeeOption(tokenInfo: _ChainAsset, amount: string, type: SWFeeType): FeeOption;
28
+ setTransactionId(transactionId: string): void;
29
+ setSelectedFeeOption(feeOption: FeeOption): void;
30
+ constructor(feeOptions: FeeOption[], chain: string, selectedFeeOption?: FeeOption);
31
+ getDefaultFeeOption(): FeeOption;
32
+ }
@@ -0,0 +1,63 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
5
+ export let SWFeeType;
6
+ (function (SWFeeType) {
7
+ SWFeeType["EIP_1559"] = "EIP_1559";
8
+ SWFeeType["LEGACY"] = "LEGACY";
9
+ SWFeeType["SUBSTRATE"] = "SUBSTRATE";
10
+ })(SWFeeType || (SWFeeType = {}));
11
+ export class SWFee {
12
+ get transactionId() {
13
+ return this._transactionId;
14
+ }
15
+ get selectedFeeOption() {
16
+ return this._selectedFeeOption;
17
+ }
18
+ static build(feeOptions, chain, selectedFeeOption) {
19
+ // todo: might need to parse metadata depending on the type
20
+ if (selectedFeeOption) {
21
+ return new SWFee(feeOptions, chain, selectedFeeOption);
22
+ } else {
23
+ const defaultFeeOption = feeOptions.find(option => option.isDefault);
24
+ return new SWFee(feeOptions, chain, defaultFeeOption);
25
+ }
26
+ }
27
+ static buildSimpleFee(tokenInfo, amount, type) {
28
+ // used for simple transaction paid in native tokens
29
+ const defaultOption = {
30
+ tokenInfo,
31
+ isDefault: _isNativeToken(tokenInfo),
32
+ // if it's the native token of the chain
33
+ amount,
34
+ type
35
+ };
36
+ return new SWFee([defaultOption], tokenInfo.originChain, defaultOption);
37
+ }
38
+ static buildFeeOption(tokenInfo, amount, type) {
39
+ // todo: calculate totalFeeValue
40
+ // todo: implement more logic to handle complicated transaction process
41
+ return {
42
+ tokenInfo,
43
+ isDefault: _isNativeToken(tokenInfo),
44
+ // if it's the native token of the chain
45
+ amount,
46
+ type
47
+ };
48
+ }
49
+ setTransactionId(transactionId) {
50
+ this._transactionId = transactionId;
51
+ }
52
+ setSelectedFeeOption(feeOption) {
53
+ this._selectedFeeOption = feeOption;
54
+ }
55
+ constructor(feeOptions, chain, selectedFeeOption) {
56
+ this.chain = chain;
57
+ this.feeOptions = feeOptions;
58
+ this._selectedFeeOption = selectedFeeOption;
59
+ }
60
+ getDefaultFeeOption() {
61
+ return this.feeOptions.find(option => option.isDefault);
62
+ }
63
+ }
@@ -1,49 +1,2 @@
1
- import BigN from 'bignumber.js';
2
- interface BaseFeeInfo {
3
- busyNetwork: boolean;
4
- }
5
- export interface EvmLegacyFeeInfo extends BaseFeeInfo {
6
- gasPrice: string;
7
- maxFeePerGas: undefined;
8
- maxPriorityFeePerGas: undefined;
9
- baseGasFee: undefined;
10
- }
11
- export interface EvmEIP1995FeeInfo extends BaseFeeInfo {
12
- gasPrice: undefined;
13
- maxFeePerGas: BigN;
14
- maxPriorityFeePerGas: BigN;
15
- baseGasFee: BigN;
16
- }
17
- export declare type EvmFeeInfo = EvmLegacyFeeInfo | EvmEIP1995FeeInfo;
18
- export interface EvmLegacyFeeInfoCache extends BaseFeeInfo {
19
- gasPrice: string;
20
- maxFeePerGas: undefined;
21
- maxPriorityFeePerGas: undefined;
22
- baseGasFee: undefined;
23
- }
24
- export interface EvmEIP1995FeeInfoCache extends BaseFeeInfo {
25
- gasPrice: undefined;
26
- maxFeePerGas: string;
27
- maxPriorityFeePerGas: string;
28
- baseGasFee: string;
29
- }
30
- export declare type EvmFeeInfoCache = EvmLegacyFeeInfoCache | EvmEIP1995FeeInfoCache;
31
- export interface InfuraFeeDetail {
32
- suggestedMaxPriorityFeePerGas: string;
33
- suggestedMaxFeePerGas: string;
34
- minWaitTimeEstimate: number;
35
- maxWaitTimeEstimate: number;
36
- }
37
- export interface InfuraFeeInfo {
38
- low: InfuraFeeDetail;
39
- medium: InfuraFeeDetail;
40
- high: InfuraFeeDetail;
41
- networkCongestion: number;
42
- estimatedBaseFee: string;
43
- latestPriorityFeeRange: [string, string];
44
- historicalPriorityFeeRange: [string, string];
45
- historicalBaseFeeRange: [string, string];
46
- priorityFeeTrend: 'down' | 'up';
47
- baseFeeTrend: 'down' | 'up';
48
- }
49
- export {};
1
+ export * from './evm';
2
+ export * from './fee';
@@ -1 +1,5 @@
1
- export {};
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from "./evm.js";
5
+ export * from "./fee.js";
@@ -0,0 +1,10 @@
1
+ import { OptimalSwapPath, OptimalSwapPathParams, SwapStepType } from '@subwallet/extension-base/types/swap';
2
+ import { OptimalYieldPath, OptimalYieldPathParams, YieldStepType } from '@subwallet/extension-base/types/yield';
3
+ export declare type OptimalProcessParams = OptimalYieldPathParams | OptimalSwapPathParams;
4
+ export declare type OptimalProcessResult = OptimalYieldPath | OptimalSwapPath;
5
+ export declare type BaseStepType = SwapStepType | YieldStepType;
6
+ export interface BaseStepDetail {
7
+ type: BaseStepType;
8
+ name: string;
9
+ metadata?: Record<string, unknown>;
10
+ }
@@ -0,0 +1 @@
1
+ export {};