@subwallet/extension-base 1.3.39-0 → 1.3.41-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 (55) hide show
  1. package/cjs/constants/environment.js +4 -2
  2. package/cjs/koni/background/handlers/Extension.js +114 -105
  3. package/cjs/packageInfo.js +1 -1
  4. package/cjs/services/balance-service/helpers/subscribe/evm.js +6 -1
  5. package/cjs/services/balance-service/transfer/xcm/index.js +26 -29
  6. package/cjs/services/balance-service/transfer/xcm/utils.js +52 -56
  7. package/cjs/services/chain-service/constants.js +6 -5
  8. package/cjs/services/chain-service/handler/CardanoApi.js +25 -35
  9. package/cjs/services/chain-service/index.js +4 -0
  10. package/cjs/services/chain-service/utils/patch.js +1 -1
  11. package/cjs/services/earning-service/handlers/native-staking/tao.js +4 -38
  12. package/cjs/services/earning-service/handlers/special.js +28 -36
  13. package/cjs/services/swap-service/handler/base-handler.js +58 -53
  14. package/cjs/services/swap-service/handler/chainflip-handler.js +29 -18
  15. package/cjs/services/swap-service/handler/kyber-handler.js +46 -34
  16. package/cjs/services/swap-service/handler/simpleswap-handler.js +79 -43
  17. package/cjs/services/swap-service/handler/uniswap-handler.js +5 -12
  18. package/cjs/services/swap-service/utils.js +48 -37
  19. package/cjs/types/environment.js +19 -0
  20. package/cjs/utils/environment.js +30 -2
  21. package/cjs/utils/fee/transfer.js +41 -33
  22. package/constants/environment.d.ts +1 -0
  23. package/constants/environment.js +2 -1
  24. package/koni/background/handlers/Extension.js +52 -43
  25. package/package.json +12 -7
  26. package/packageInfo.js +1 -1
  27. package/services/balance-service/helpers/subscribe/evm.js +6 -1
  28. package/services/balance-service/transfer/xcm/index.d.ts +1 -2
  29. package/services/balance-service/transfer/xcm/index.js +23 -26
  30. package/services/balance-service/transfer/xcm/utils.d.ts +38 -6
  31. package/services/balance-service/transfer/xcm/utils.js +51 -55
  32. package/services/chain-service/constants.d.ts +1 -0
  33. package/services/chain-service/constants.js +6 -5
  34. package/services/chain-service/handler/CardanoApi.d.ts +1 -5
  35. package/services/chain-service/handler/CardanoApi.js +26 -34
  36. package/services/chain-service/index.js +4 -0
  37. package/services/chain-service/utils/patch.js +1 -1
  38. package/services/earning-service/handlers/native-staking/tao.d.ts +0 -11
  39. package/services/earning-service/handlers/native-staking/tao.js +4 -24
  40. package/services/earning-service/handlers/special.js +12 -20
  41. package/services/swap-service/handler/base-handler.js +11 -6
  42. package/services/swap-service/handler/chainflip-handler.d.ts +0 -2
  43. package/services/swap-service/handler/chainflip-handler.js +25 -13
  44. package/services/swap-service/handler/kyber-handler.d.ts +0 -1
  45. package/services/swap-service/handler/kyber-handler.js +46 -33
  46. package/services/swap-service/handler/simpleswap-handler.d.ts +0 -1
  47. package/services/swap-service/handler/simpleswap-handler.js +80 -43
  48. package/services/swap-service/handler/uniswap-handler.js +6 -13
  49. package/services/swap-service/utils.d.ts +0 -13
  50. package/services/swap-service/utils.js +48 -34
  51. package/types/environment.d.ts +9 -0
  52. package/types/environment.js +13 -0
  53. package/utils/environment.d.ts +2 -0
  54. package/utils/environment.js +27 -1
  55. package/utils/fee/transfer.js +11 -3
@@ -1,16 +1,16 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
4
  import { fetchParaSpellChainMap } from '@subwallet/extension-base/constants/paraspell-chain-map';
6
- import { BasicTxErrorType } from '@subwallet/extension-base/types';
5
+ import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
6
+ import { fetchFromProxyService } from '@subwallet/extension-base/utils';
7
7
  import { assert, compactToU8a, isHex, u8aConcat, u8aEq } from '@polkadot/util';
8
- const paraSpellEndpoint = 'https://api.lightspell.xyz';
8
+ const version = '/v3';
9
9
  const paraSpellApi = {
10
- buildXcm: `${paraSpellEndpoint}/x-transfer`,
11
- dryRunXcm: `${paraSpellEndpoint}/dry-run`
10
+ buildXcm: `${version}/x-transfer`,
11
+ dryRunXcm: `${version}/dry-run`,
12
+ feeXcm: `${version}/xcm-fee`
12
13
  };
13
- const paraSpellKey = process.env.PARASPELL_API_KEY || '';
14
14
  function txHexToSubmittableExtrinsic(api, hex) {
15
15
  try {
16
16
  assert(isHex(hex), 'Expected a hex-encoded call');
@@ -73,7 +73,7 @@ export async function buildXcm(request) {
73
73
  substrateApi
74
74
  } = request;
75
75
  if (!substrateApi) {
76
- return Promise.reject(new Error('Substrate API is not available'));
76
+ throw new Error('Substrate API is not available');
77
77
  }
78
78
  const psAssetType = (_originTokenInfo$meta = originTokenInfo.metadata) === null || _originTokenInfo$meta === void 0 ? void 0 : _originTokenInfo$meta.paraSpellAssetType;
79
79
  const psAssetValue = (_originTokenInfo$meta2 = originTokenInfo.metadata) === null || _originTokenInfo$meta2 === void 0 ? void 0 : _originTokenInfo$meta2.paraSpellValue;
@@ -87,13 +87,12 @@ export async function buildXcm(request) {
87
87
  to: paraSpellChainMap[destinationChain.slug],
88
88
  currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
89
89
  };
90
- const response = await fetch(paraSpellApi.buildXcm, {
90
+ const response = await fetchFromProxyService(ProxyServiceRoute.PARASPELL, paraSpellApi.buildXcm, {
91
91
  method: 'POST',
92
92
  body: JSON.stringify(bodyData),
93
93
  headers: {
94
94
  'Content-Type': 'application/json',
95
- Accept: 'application/json',
96
- 'X-API-KEY': paraSpellKey
95
+ Accept: 'application/json'
97
96
  }
98
97
  });
99
98
  if (!response.ok) {
@@ -104,8 +103,6 @@ export async function buildXcm(request) {
104
103
  const chainApi = await substrateApi.isReady;
105
104
  return txHexToSubmittableExtrinsic(chainApi.api, extrinsicHex);
106
105
  }
107
-
108
- // dry run can fail due to sender address & amount token
109
106
  export async function dryRunXcm(request) {
110
107
  var _originTokenInfo$meta3, _originTokenInfo$meta4;
111
108
  const {
@@ -120,76 +117,75 @@ export async function dryRunXcm(request) {
120
117
  const psAssetType = (_originTokenInfo$meta3 = originTokenInfo.metadata) === null || _originTokenInfo$meta3 === void 0 ? void 0 : _originTokenInfo$meta3.paraSpellAssetType;
121
118
  const psAssetValue = (_originTokenInfo$meta4 = originTokenInfo.metadata) === null || _originTokenInfo$meta4 === void 0 ? void 0 : _originTokenInfo$meta4.paraSpellValue;
122
119
  if (!psAssetType || !psAssetValue) {
123
- throw new Error('Token is not support XCM at this time'); // todo: content
120
+ throw new Error('Token is not support XCM at this time');
124
121
  }
125
-
126
- let dryRunInfo;
127
- try {
128
- const bodyData = {
129
- senderAddress: sender,
130
- address: recipient,
131
- from: paraSpellChainMap[originChain.slug],
132
- to: paraSpellChainMap[destinationChain.slug],
133
- currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
134
- };
135
- const response = await fetch(paraSpellApi.dryRunXcm, {
136
- method: 'POST',
137
- body: JSON.stringify(bodyData),
138
- headers: {
139
- 'Content-Type': 'application/json',
140
- Accept: 'application/json',
141
- 'X-API-KEY': paraSpellKey
122
+ const bodyData = {
123
+ senderAddress: sender,
124
+ address: recipient,
125
+ from: paraSpellChainMap[originChain.slug],
126
+ to: paraSpellChainMap[destinationChain.slug],
127
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
128
+ };
129
+ const response = await fetchFromProxyService(ProxyServiceRoute.PARASPELL, paraSpellApi.dryRunXcm, {
130
+ method: 'POST',
131
+ body: JSON.stringify(bodyData),
132
+ headers: {
133
+ 'Content-Type': 'application/json',
134
+ Accept: 'application/json'
135
+ }
136
+ });
137
+ if (!response.ok) {
138
+ const error = await response.json();
139
+ return {
140
+ origin: {
141
+ success: false,
142
+ failureReason: error.message
142
143
  }
143
- });
144
- dryRunInfo = await response.json();
145
- } catch (e) {
146
- console.error('Unable to dry run', e);
147
- }
148
- if (!dryRunInfo || !dryRunInfo.success) {
149
- throw new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again');
144
+ };
150
145
  }
151
- return dryRunInfo;
146
+ return await response.json();
152
147
  }
153
- export async function dryRunXcmV2(request) {
154
- var _originTokenInfo$meta5, _originTokenInfo$meta6;
148
+ export async function estimateXcmFee(request) {
149
+ var _fromTokenInfo$metada, _fromTokenInfo$metada2;
155
150
  const {
156
- destinationChain,
157
- originChain,
158
- originTokenInfo,
151
+ fromChainInfo,
152
+ fromTokenInfo,
159
153
  recipient,
160
154
  sender,
161
- sendingValue
155
+ toChainInfo,
156
+ value
162
157
  } = request;
163
158
  const paraSpellChainMap = await fetchParaSpellChainMap();
164
- const psAssetType = (_originTokenInfo$meta5 = originTokenInfo.metadata) === null || _originTokenInfo$meta5 === void 0 ? void 0 : _originTokenInfo$meta5.paraSpellAssetType;
165
- const psAssetValue = (_originTokenInfo$meta6 = originTokenInfo.metadata) === null || _originTokenInfo$meta6 === void 0 ? void 0 : _originTokenInfo$meta6.paraSpellValue;
159
+ const psAssetType = (_fromTokenInfo$metada = fromTokenInfo.metadata) === null || _fromTokenInfo$metada === void 0 ? void 0 : _fromTokenInfo$metada.paraSpellAssetType;
160
+ const psAssetValue = (_fromTokenInfo$metada2 = fromTokenInfo.metadata) === null || _fromTokenInfo$metada2 === void 0 ? void 0 : _fromTokenInfo$metada2.paraSpellValue;
166
161
  if (!psAssetType || !psAssetValue) {
167
- throw new Error('Token is not support XCM at this time');
162
+ console.error('Lack of paraspell metadata');
163
+ return undefined;
168
164
  }
169
165
  const bodyData = {
170
166
  senderAddress: sender,
171
167
  address: recipient,
172
- from: paraSpellChainMap[originChain.slug],
173
- to: paraSpellChainMap[destinationChain.slug],
174
- currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
168
+ from: paraSpellChainMap[fromChainInfo.slug],
169
+ to: paraSpellChainMap[toChainInfo.slug],
170
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, value)
175
171
  };
176
- const response = await fetch(paraSpellApi.dryRunXcm, {
172
+ const response = await fetchFromProxyService(ProxyServiceRoute.PARASPELL, paraSpellApi.feeXcm, {
177
173
  method: 'POST',
178
174
  body: JSON.stringify(bodyData),
179
175
  headers: {
180
176
  'Content-Type': 'application/json',
181
- Accept: 'application/json',
182
- 'X-API-KEY': paraSpellKey
177
+ Accept: 'application/json'
183
178
  }
184
179
  });
185
180
  if (!response.ok) {
186
- const error = await response.json();
187
- throw new Error(error.message);
181
+ console.error('Failed to request estimate fee');
182
+ return undefined;
188
183
  }
189
184
  return await response.json();
190
185
  }
191
186
  function createParaSpellCurrency(assetType, assetValue, amount) {
192
187
  // todo: handle complex conditions for asset has same symbol in a chain: Id, Multi-location, ...
188
+ // todo: or update all asset to use multi-location
193
189
  return {
194
190
  [assetType]: assetValue,
195
191
  amount
@@ -21,6 +21,7 @@ export declare const _BALANCE_CHAIN_GROUP: {
21
21
  centrifuge: string[];
22
22
  supportBridged: string[];
23
23
  bittensor: string[];
24
+ moonbeam: string[];
24
25
  };
25
26
  export declare const _BALANCE_TOKEN_GROUP: {
26
27
  crab: string[];
@@ -29,13 +29,14 @@ export const _BALANCE_CHAIN_GROUP = {
29
29
  kintsugi: ['kintsugi', 'interlay', 'kintsugi_test', 'mangatax_para'],
30
30
  genshiro: ['genshiro_testnet', 'genshiro'],
31
31
  equilibrium_parachain: ['equilibrium_parachain'],
32
- bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network'],
33
- statemine: ['statemine', 'astar', 'shiden', 'statemint', 'moonbeam', 'moonbase', 'moonriver', 'crabParachain', 'darwinia2', 'parallel', 'calamari', 'manta_network', 'rococo_assethub', 'liberlandTest', 'liberland', 'dentnet', 'pangolin', 'crust', 'phala', 'shibuya', 'dbcchain', 'westend_assethub'],
32
+ bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network', 'jamton'],
33
+ statemine: ['statemine', 'astar', 'shiden', 'statemint', 'crabParachain', 'darwinia2', 'parallel', 'calamari', 'manta_network', 'rococo_assethub', 'liberlandTest', 'liberland', 'dentnet', 'pangolin', 'crust', 'phala', 'shibuya', 'dbcchain', 'westend_assethub', 'chainflip_assethub'],
34
34
  kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'],
35
35
  // perhaps there are some runtime updates
36
36
  centrifuge: ['centrifuge'],
37
37
  supportBridged: ['rococo_assethub', 'statemint', 'statemine', 'polimec'],
38
- bittensor: ['bittensor', 'bittensor_testnet']
38
+ bittensor: ['bittensor', 'bittensor_testnet'],
39
+ moonbeam: ['moonbeam', 'moonriver', 'moonbase']
39
40
  };
40
41
  export const _BALANCE_TOKEN_GROUP = {
41
42
  crab: ['CKTON', 'PKTON'],
@@ -254,11 +255,11 @@ export const _TRANSFER_CHAIN_GROUP = {
254
255
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
255
256
  // crab: ['crab', 'pangolin'],
256
257
  bitcountry: ['pioneer', 'bitcountry'],
257
- statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain', 'westend_assethub'],
258
+ statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain', 'westend_assethub', 'chainflip_assethub'],
258
259
  riochain: ['riochain'],
259
260
  sora_substrate: ['sora_substrate'],
260
261
  avail: ['kate', 'goldberg_testnet'],
261
- pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot'],
262
+ pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot', 'jamton'],
262
263
  centrifuge: ['centrifuge'],
263
264
  disable_transfer: ['crab', 'pangolin']
264
265
  };
@@ -3,10 +3,6 @@ import { _ApiOptions } from '@subwallet/extension-base/services/chain-service/ha
3
3
  import { _CardanoApi, _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
4
4
  import { PromiseHandler } from '@subwallet/extension-base/utils';
5
5
  import { BehaviorSubject } from 'rxjs';
6
- export declare const API_KEY: {
7
- mainnet: string;
8
- testnet: string;
9
- };
10
6
  export declare class CardanoApi implements _CardanoApi {
11
7
  chainSlug: string;
12
8
  apiUrl: string;
@@ -18,11 +14,11 @@ export declare class CardanoApi implements _CardanoApi {
18
14
  isApiReadyOnce: boolean;
19
15
  isReadyHandler: PromiseHandler<_CardanoApi>;
20
16
  isTestnet: boolean;
21
- private projectId;
22
17
  providerName: string;
23
18
  constructor(chainSlug: string, apiUrl: string, { isTestnet, providerName }: _ApiOptions);
24
19
  get isApiConnected(): boolean;
25
20
  get connectionStatus(): _ChainConnectionStatus;
21
+ private fetchCardano;
26
22
  private updateConnectionStatus;
27
23
  get isReady(): Promise<_CardanoApi>;
28
24
  updateApiUrl(apiUrl: string): Promise<void>;
@@ -3,13 +3,16 @@
3
3
 
4
4
  import { cborToBytes, retryCardanoTxStatus } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/cardano/utils';
5
5
  import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
6
- import { createPromiseHandler } from '@subwallet/extension-base/utils';
6
+ import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
7
+ import { createPromiseHandler, fetchFromProxyService } from '@subwallet/extension-base/utils';
7
8
  import { BehaviorSubject } from 'rxjs';
8
9
  import { hexAddPrefix, isHex } from '@polkadot/util';
9
- export const API_KEY = {
10
- mainnet: process.env.BLOCKFROST_API_KEY_MAIN || '',
11
- testnet: process.env.BLOCKFROST_API_KEY_PREP || ''
12
- };
10
+
11
+ // export const API_KEY = {
12
+ // mainnet: process.env.BLOCKFROST_API_KEY_MAIN || '',
13
+ // testnet: process.env.BLOCKFROST_API_KEY_PREP || ''
14
+ // };
15
+
13
16
  export class CardanoApi {
14
17
  // private api: BlockFrostAPI;
15
18
 
@@ -25,7 +28,6 @@ export class CardanoApi {
25
28
  this.chainSlug = chainSlug;
26
29
  this.apiUrl = apiUrl;
27
30
  this.isTestnet = isTestnet !== null && isTestnet !== void 0 ? isTestnet : true;
28
- this.projectId = isTestnet ? API_KEY.testnet : API_KEY.mainnet;
29
31
  this.providerName = providerName || 'unknown';
30
32
  // this.api = this.createProvider(isTestnet);
31
33
  this.isReadyHandler = createPromiseHandler();
@@ -37,6 +39,9 @@ export class CardanoApi {
37
39
  get connectionStatus() {
38
40
  return this.connectionStatusSubject.getValue();
39
41
  }
42
+ fetchCardano(path, options) {
43
+ return fetchFromProxyService(ProxyServiceRoute.CARDANO, path, options, this.isTestnet);
44
+ }
40
45
  updateConnectionStatus(status) {
41
46
  const isConnected = status === _ChainConnectionStatus.CONNECTED;
42
47
  if (isConnected !== this.isApiConnectedSubject.value) {
@@ -107,12 +112,9 @@ export class CardanoApi {
107
112
  }
108
113
  async getBalanceMap(address) {
109
114
  try {
110
- const url = this.isTestnet ? `https://cardano-preprod.blockfrost.io/api/v0/addresses/${address}` : `https://cardano-mainnet.blockfrost.io/api/v0/addresses/${address}`;
111
- const response = await fetch(url, {
112
- method: 'GET',
113
- headers: {
114
- Project_id: this.projectId
115
- }
115
+ const path = `/addresses/${address}`;
116
+ const response = await this.fetchCardano(path, {
117
+ method: 'GET'
116
118
  });
117
119
  const addressBalance = await response.json();
118
120
  return addressBalance.amount;
@@ -123,13 +125,10 @@ export class CardanoApi {
123
125
  }
124
126
  async getUtxos(address, page, limit) {
125
127
  try {
126
- let url = this.isTestnet ? `https://cardano-preprod.blockfrost.io/api/v0/addresses/${address}/utxos` : `https://cardano-mainnet.blockfrost.io/api/v0/addresses/${address}/utxos`;
127
- url += `?page=${page}&count=${limit}`;
128
- const response = await fetch(url, {
129
- method: 'GET',
130
- headers: {
131
- Project_id: this.projectId
132
- }
128
+ let path = `/addresses/${address}/utxos`;
129
+ path += `?page=${page}&count=${limit}`;
130
+ const response = await this.fetchCardano(path, {
131
+ method: 'GET'
133
132
  });
134
133
  const utxos = await response.json();
135
134
  return utxos;
@@ -140,12 +139,9 @@ export class CardanoApi {
140
139
  }
141
140
  async getSpecificUtxo(txHash) {
142
141
  try {
143
- const url = this.isTestnet ? `https://cardano-preprod.blockfrost.io/api/v0/txs/${txHash}/utxos` : `https://cardano-mainnet.blockfrost.io/api/v0/txs/${txHash}/utxos`;
144
- const response = await fetch(url, {
145
- method: 'GET',
146
- headers: {
147
- Project_id: this.projectId
148
- }
142
+ const path = `/txs/${txHash}/utxos`;
143
+ const response = await this.fetchCardano(path, {
144
+ method: 'GET'
149
145
  });
150
146
  const utxo = await response.json();
151
147
  return utxo;
@@ -156,11 +152,10 @@ export class CardanoApi {
156
152
  }
157
153
  async sendCardanoTxReturnHash(tx) {
158
154
  try {
159
- const url = this.isTestnet ? 'https://cardano-preprod.blockfrost.io/api/v0/tx/submit' : 'https://cardano-mainnet.blockfrost.io/api/v0/tx/submit';
160
- const response = await fetch(url, {
155
+ const path = '/tx/submit';
156
+ const response = await this.fetchCardano(path, {
161
157
  method: 'POST',
162
158
  headers: {
163
- Project_id: this.projectId,
164
159
  'Content-Type': 'application/cbor'
165
160
  },
166
161
  body: cborToBytes(tx)
@@ -180,12 +175,9 @@ export class CardanoApi {
180
175
  async getStatusByTxHash(txHash, ttl) {
181
176
  const cronTime = 30000;
182
177
  return retryCardanoTxStatus(async () => {
183
- const url = this.isTestnet ? `https://cardano-preprod.blockfrost.io/api/v0/txs/${txHash}` : `https://cardano-mainnet.blockfrost.io/api/v0/txs/${txHash}`;
184
- const response = await fetch(url, {
185
- method: 'GET',
186
- headers: {
187
- Project_id: this.projectId
188
- }
178
+ const path = `/txs/${txHash}`;
179
+ const response = await this.fetchCardano(path, {
180
+ method: 'GET'
189
181
  });
190
182
  const txInfo = await response.json();
191
183
  if (txInfo.block && txInfo.hash && txInfo.index >= 0) {
@@ -1233,6 +1233,10 @@ export class ChainService {
1233
1233
  deprecated = true;
1234
1234
  break;
1235
1235
  }
1236
+ if (defaultChainAsset.slug === storedAssetInfo.slug) {
1237
+ duplicated = true;
1238
+ break;
1239
+ }
1236
1240
  }
1237
1241
  if (!duplicated && !deprecated) {
1238
1242
  mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
@@ -5,7 +5,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
5
5
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
6
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
7
7
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
8
- const ChainListVersion = '0.2.104'; // update this when build chainlist
8
+ const ChainListVersion = '0.2.105'; // update this when build chainlist
9
9
 
10
10
  // todo: move this interface to chainlist
11
11
 
@@ -37,17 +37,6 @@ interface Validator {
37
37
  take: string;
38
38
  apr: string;
39
39
  }
40
- export declare const BITTENSOR_API_KEY_1: string;
41
- export declare const BITTENSOR_API_KEY_2: string;
42
- export declare const BITTENSOR_API_KEY_3: string;
43
- export declare const BITTENSOR_API_KEY_4: string;
44
- export declare const BITTENSOR_API_KEY_5: string;
45
- export declare const BITTENSOR_API_KEY_6: string;
46
- export declare const BITTENSOR_API_KEY_7: string;
47
- export declare const BITTENSOR_API_KEY_8: string;
48
- export declare const BITTENSOR_API_KEY_9: string;
49
- export declare const BITTENSOR_API_KEY_10: string;
50
- export declare const bittensorApiKey: () => string;
51
40
  export declare class BittensorCache {
52
41
  private static instance;
53
42
  private cache;
@@ -8,31 +8,13 @@ import { getEarningStatusByNominations } from '@subwallet/extension-base/koni/ap
8
8
  import { _getAssetDecimals, _getAssetSymbol } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
10
10
  import { BasicTxErrorType, EarningStatus } from '@subwallet/extension-base/types';
11
- import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
11
+ import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
12
+ import { fetchFromProxyService, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
12
13
  import BigN from 'bignumber.js';
13
14
  import { t } from 'i18next';
14
15
  import { BN, BN_ZERO } from '@polkadot/util';
15
16
  import { calculateReward } from "../../utils/index.js";
16
17
  import { DEFAULT_DTAO_MINBOND } from "./dtao.js";
17
- export const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
18
- export const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
19
- export const BITTENSOR_API_KEY_3 = process.env.BITTENSOR_API_KEY_3 || '';
20
- export const BITTENSOR_API_KEY_4 = process.env.BITTENSOR_API_KEY_4 || '';
21
- export const BITTENSOR_API_KEY_5 = process.env.BITTENSOR_API_KEY_5 || '';
22
- export const BITTENSOR_API_KEY_6 = process.env.BITTENSOR_API_KEY_6 || '';
23
- export const BITTENSOR_API_KEY_7 = process.env.BITTENSOR_API_KEY_7 || '';
24
- export const BITTENSOR_API_KEY_8 = process.env.BITTENSOR_API_KEY_8 || '';
25
- export const BITTENSOR_API_KEY_9 = process.env.BITTENSOR_API_KEY_9 || '';
26
- export const BITTENSOR_API_KEY_10 = process.env.BITTENSOR_API_KEY_10 || '';
27
- function random(...keys) {
28
- const validKeys = keys.filter(key => key);
29
- const randomIndex = Math.floor(Math.random() * validKeys.length);
30
- return validKeys[randomIndex];
31
- }
32
- export const bittensorApiKey = () => {
33
- return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6, BITTENSOR_API_KEY_7, BITTENSOR_API_KEY_8, BITTENSOR_API_KEY_9, BITTENSOR_API_KEY_10);
34
- };
35
-
36
18
  /* Fetch data */
37
19
  export class BittensorCache {
38
20
  static instance = null;
@@ -59,13 +41,11 @@ export class BittensorCache {
59
41
  return this.promise;
60
42
  }
61
43
  async fetchData() {
62
- const apiKey = bittensorApiKey();
63
44
  try {
64
- const resp = await fetch('https://api.taostats.io/api/validator/latest/v1?limit=50', {
45
+ const resp = await fetchFromProxyService(ProxyServiceRoute.BITTENSOR, '/validator/latest/v1?limit=50', {
65
46
  method: 'GET',
66
47
  headers: {
67
- 'Content-Type': 'application/json',
68
- Authorization: `${apiKey}`
48
+ 'Content-Type': 'application/json'
69
49
  }
70
50
  });
71
51
  if (!resp.ok) {
@@ -5,7 +5,8 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
5
5
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { ALL_ACCOUNT_KEY, XCM_FEE_RATIO, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
7
7
  import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
8
- import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
8
+ import { createXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
9
+ import { estimateXcmFee } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
9
10
  import { _getAssetDecimals, _getAssetExistentialDeposit, _getAssetName, _getAssetSymbol, _getChainNativeTokenSlug, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
10
11
  import { BasicTxErrorType, YieldStepType, YieldValidationStatus } from '@subwallet/extension-base/types';
11
12
  import { createPromiseHandler, formatNumber } from '@subwallet/extension-base/utils';
@@ -217,29 +218,20 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
217
218
  const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
218
219
  const symbol = altInputTokenInfo.symbol;
219
220
  const networkName = altChainInfo.name;
220
- const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
221
- const id = getId();
222
- const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
223
- const xcmRequest = {
224
- sender: address,
225
- originTokenInfo: altInputTokenInfo,
226
- destinationTokenInfo: inputTokenInfo,
227
- sendingValue: bnAmount.toString(),
228
- recipient: address,
229
- destinationChain: this.chainInfo,
230
- originChain: altChainInfo,
231
- substrateApi: xcmOriginSubstrateApi,
232
- feeInfo
233
- };
234
221
 
235
222
  // TODO: calculate fee for destination chain
236
- let xcmFee;
237
- const xcmFeeByDryRun = await dryRunXcmExtrinsicV2(xcmRequest);
238
- if (xcmFeeByDryRun.fee) {
239
- xcmFee = BigN(xcmFeeByDryRun.fee).multipliedBy(XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
240
- } else {
223
+ const xcmFeeInfo = await estimateXcmFee({
224
+ fromChainInfo: altChainInfo,
225
+ fromTokenInfo: altInputTokenInfo,
226
+ toChainInfo: this.chainInfo,
227
+ recipient: address,
228
+ sender: address,
229
+ value: bnAmount.toString()
230
+ });
231
+ if (!xcmFeeInfo) {
241
232
  throw new Error('Error estimating XCM fee');
242
233
  }
234
+ const xcmFee = BigN(xcmFeeInfo.origin.fee).multipliedBy(XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
243
235
  const fee = {
244
236
  slug: altInputTokenSlug,
245
237
  amount: xcmFee
@@ -7,8 +7,9 @@ import { validateSpendingAndFeePayment } from '@subwallet/extension-base/core/lo
7
7
  import { _isAccountActive } from '@subwallet/extension-base/core/substrate/system-pallet';
8
8
  import { _isAcrossBridgeXcm, _isSnowBridgeXcm, _isXcmWithinSameConsensus } from '@subwallet/extension-base/core/substrate/xcm-parser';
9
9
  import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
10
- import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
10
+ import { createXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
11
11
  import { _isAcrossChainBridge, AcrossErrorMsg } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
12
+ import { estimateXcmFee } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
12
13
  import { _getAssetDecimals, _getAssetOriginChain, _getAssetSymbol, _getChainNativeTokenSlug, _getTokenMinAmount, _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
13
14
  import { DEFAULT_EXCESS_AMOUNT_WEIGHT, FEE_RATE_MULTIPLIER } from '@subwallet/extension-base/services/swap-service/utils';
14
15
  import { BasicTxErrorType, SwapStepType, TransferTxErrorType } from '@subwallet/extension-base/types';
@@ -121,11 +122,15 @@ export class SwapBaseHandler {
121
122
  };
122
123
 
123
124
  // TODO: calculate fee for destination chain
124
- const bridgeFeeByDryRun = await dryRunXcmExtrinsicV2(xcmRequest);
125
- if (!bridgeFeeByDryRun.fee) {
126
- return undefined;
127
- }
128
- const estimatedBridgeFee = BigN(bridgeFeeByDryRun.fee).multipliedBy(FEE_RATE_MULTIPLIER.medium).toFixed(0, 1);
125
+ const xcmFeeInfo = await estimateXcmFee({
126
+ fromChainInfo: xcmRequest.originChain,
127
+ fromTokenInfo: xcmRequest.originTokenInfo,
128
+ toChainInfo: xcmRequest.destinationChain,
129
+ recipient: xcmRequest.recipient,
130
+ sender: xcmRequest.sender,
131
+ value: xcmRequest.sendingValue
132
+ });
133
+ const estimatedBridgeFee = BigN((xcmFeeInfo === null || xcmFeeInfo === void 0 ? void 0 : xcmFeeInfo.origin.fee) || '0').multipliedBy(FEE_RATE_MULTIPLIER.medium).toFixed(0, 1);
129
134
  const fee = {
130
135
  feeComponent: [{
131
136
  feeType: SwapFeeType.NETWORK_FEE,
@@ -5,12 +5,10 @@ import { ChainService } from '@subwallet/extension-base/services/chain-service';
5
5
  import FeeService from '@subwallet/extension-base/services/fee-service/service';
6
6
  import { SwapBaseInterface } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
7
7
  import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
8
- export declare const CHAINFLIP_BROKER_API: string;
9
8
  export declare class ChainflipSwapHandler implements SwapBaseInterface {
10
9
  private readonly isTestnet;
11
10
  private swapBaseHandler;
12
11
  providerSlug: SwapProviderId;
13
- private baseUrl;
14
12
  constructor(chainService: ChainService, balanceService: BalanceService, feeService: FeeService, isTestnet?: boolean);
15
13
  get chainService(): ChainService;
16
14
  get balanceService(): BalanceService;
@@ -8,15 +8,17 @@ import { getERC20TransactionObject, getEVMTransactionObject } from '@subwallet/e
8
8
  import { createSubstrateExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/token';
9
9
  import { _getAssetSymbol, _getContractAddressOfToken, _isChainSubstrateCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  import { SwapBaseHandler } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
11
- import { getChainflipSwap } from '@subwallet/extension-base/services/swap-service/utils';
12
11
  import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
13
- import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
12
+ import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
13
+ import { _reformatAddressWithChain, fetchFromProxyService } from '@subwallet/extension-base/utils';
14
14
  import { getId } from '@subwallet/extension-base/utils/getId';
15
15
  import BigNumber from 'bignumber.js';
16
16
  const INTERMEDIARY_MAINNET_ASSET_SLUG = COMMON_ASSETS.USDC_ETHEREUM;
17
17
  const INTERMEDIARY_TESTNET_ASSET_SLUG = COMMON_ASSETS.USDC_SEPOLIA;
18
- export const CHAINFLIP_BROKER_API = process.env.CHAINFLIP_BROKER_API || '';
19
18
  export class ChainflipSwapHandler {
19
+ // private baseUrl: string;
20
+ // private assetsUrl: string;
21
+
20
22
  constructor(chainService, balanceService, feeService, isTestnet = true) {
21
23
  this.swapBaseHandler = new SwapBaseHandler({
22
24
  chainService,
@@ -27,8 +29,10 @@ export class ChainflipSwapHandler {
27
29
  });
28
30
  this.isTestnet = isTestnet;
29
31
  this.providerSlug = isTestnet ? SwapProviderId.CHAIN_FLIP_TESTNET : SwapProviderId.CHAIN_FLIP_MAINNET;
30
- this.baseUrl = getChainflipSwap(isTestnet);
32
+ // this.baseUrl = getChainflipSwap(isTestnet);
33
+ // this.assetsUrl = getAssetsUrl(isTestnet);
31
34
  }
35
+
32
36
  get chainService() {
33
37
  return this.swapBaseHandler.chainService;
34
38
  }
@@ -76,23 +80,31 @@ export class ChainflipSwapHandler {
76
80
  if (processMetadata.destChain !== quoteMetadata.destChain || processMetadata.srcChain !== quoteMetadata.srcChain) {
77
81
  throw new Error('Metadata for Chainflip not found');
78
82
  }
83
+ const assetsResponse = await fetchFromProxyService(ProxyServiceRoute.CHAINFLIP, '/assets', {
84
+ method: 'GET'
85
+ }, this.isTestnet);
86
+ const _allAssets = await assetsResponse.json();
87
+ const allAssets = _allAssets.assets;
88
+ const sourceAsset = allAssets.find(asset => asset.network === processMetadata.srcChain && asset.ticker === fromAssetId);
89
+ const destinationAsset = allAssets.find(asset => asset.network === processMetadata.destChain && asset.ticker === toAssetId);
90
+ if (!sourceAsset || !destinationAsset) {
91
+ throw new Error('Error get Chainflip data');
92
+ }
79
93
  const depositParams = {
80
- sourceChain: processMetadata.srcChain,
81
94
  destinationAddress: receiver,
82
- destinationAsset: toAssetId,
83
- destinationChain: processMetadata.destChain,
95
+ destinationAsset: destinationAsset.id,
96
+ sourceAsset: sourceAsset.id,
84
97
  minimumPrice: minReceive,
85
98
  // minimum accepted price for swaps through the channel
86
99
  refundAddress: address,
87
100
  // address to which assets are refunded
88
- retryDurationInBlocks: '100',
89
- // 100 blocks * 6 seconds = 10 minutes before deposits are refunded
90
- sourceAsset: fromAssetId
101
+ retryDurationInBlocks: '100' // 100 blocks * 6 seconds = 10 minutes before deposits are refunded
91
102
  };
92
- const url = `${this.baseUrl}&${new URLSearchParams(depositParams).toString()}`;
93
- const response = await fetch(url, {
103
+
104
+ const path = `/swap?${new URLSearchParams(depositParams).toString()}`;
105
+ const response = await fetchFromProxyService(ProxyServiceRoute.CHAINFLIP, path, {
94
106
  method: 'GET'
95
- });
107
+ }, this.isTestnet);
96
108
  const data = await response.json();
97
109
  if (!data.id || !data.address || data.address === '' || !data.issuedBlock || !data.network || !data.channelId) {
98
110
  throw new Error('Error get Chainflip data');
@@ -8,7 +8,6 @@ import { SwapBaseInterface } from './base-handler';
8
8
  export interface KyberSwapQuoteMetadata {
9
9
  priceImpact?: string;
10
10
  }
11
- export declare const KYBER_CLIENT_ID: string;
12
11
  export declare class KyberHandler implements SwapBaseInterface {
13
12
  private swapBaseHandler;
14
13
  transactionService: TransactionService;