@subwallet/extension-base 1.3.77-0 → 1.3.78-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 (74) hide show
  1. package/background/KoniTypes.d.ts +2 -0
  2. package/cjs/core/logic-validation/index.js +1 -1
  3. package/cjs/core/substrate/xcm-parser.js +10 -1
  4. package/cjs/koni/background/handlers/Extension.js +35 -8
  5. package/cjs/koni/background/handlers/State.js +20 -0
  6. package/cjs/packageInfo.js +1 -1
  7. package/cjs/services/balance-service/helpers/subscribe/evm.js +85 -6
  8. package/cjs/services/balance-service/helpers/subscribe/index.js +2 -1
  9. package/cjs/services/balance-service/index.js +6 -2
  10. package/cjs/services/balance-service/transfer/token.js +15 -0
  11. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/index.js +27 -0
  12. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.js +58 -0
  13. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/utils.js +36 -0
  14. package/cjs/services/balance-service/transfer/xcm/index.js +61 -2
  15. package/cjs/services/balance-service/transfer/xcm/utils.js +94 -6
  16. package/cjs/services/chain-service/constants.js +4 -2
  17. package/cjs/services/chain-service/utils/patch.js +1 -1
  18. package/cjs/services/earning-service/constants/chains.js +4 -2
  19. package/cjs/services/earning-service/handlers/special.js +82 -65
  20. package/cjs/services/earning-service/service.js +1 -0
  21. package/cjs/services/swap-service/handler/bittensor-handler.js +197 -0
  22. package/cjs/services/swap-service/index.js +7 -0
  23. package/cjs/services/transaction-service/index.js +1 -0
  24. package/cjs/types/balance/index.js +1 -0
  25. package/cjs/types/swap/index.js +3 -1
  26. package/cjs/utils/fee/transfer.js +20 -5
  27. package/core/logic-validation/index.js +1 -1
  28. package/core/substrate/xcm-parser.d.ts +2 -0
  29. package/core/substrate/xcm-parser.js +8 -1
  30. package/koni/background/handlers/Extension.js +36 -9
  31. package/koni/background/handlers/State.d.ts +1 -0
  32. package/koni/background/handlers/State.js +20 -0
  33. package/package.json +26 -6
  34. package/packageInfo.js +1 -1
  35. package/services/balance-service/helpers/subscribe/evm.d.ts +1 -0
  36. package/services/balance-service/helpers/subscribe/evm.js +76 -1
  37. package/services/balance-service/helpers/subscribe/index.js +2 -1
  38. package/services/balance-service/index.js +6 -2
  39. package/services/balance-service/transfer/token.d.ts +2 -1
  40. package/services/balance-service/transfer/token.js +15 -0
  41. package/services/balance-service/transfer/xcm/bittensorBridge/index.d.ts +2 -0
  42. package/services/balance-service/transfer/xcm/bittensorBridge/index.js +5 -0
  43. package/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.d.ts +6 -0
  44. package/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.js +50 -0
  45. package/services/balance-service/transfer/xcm/bittensorBridge/utils.d.ts +8 -0
  46. package/services/balance-service/transfer/xcm/bittensorBridge/utils.js +29 -0
  47. package/services/balance-service/transfer/xcm/index.d.ts +5 -0
  48. package/services/balance-service/transfer/xcm/index.js +57 -2
  49. package/services/balance-service/transfer/xcm/utils.d.ts +3 -2
  50. package/services/balance-service/transfer/xcm/utils.js +87 -1
  51. package/services/chain-service/constants.d.ts +2 -0
  52. package/services/chain-service/constants.js +4 -2
  53. package/services/chain-service/utils/patch.d.ts +1 -1
  54. package/services/chain-service/utils/patch.js +1 -1
  55. package/services/earning-service/constants/chains.d.ts +1 -0
  56. package/services/earning-service/constants/chains.js +2 -1
  57. package/services/earning-service/handlers/special.d.ts +1 -1
  58. package/services/earning-service/handlers/special.js +85 -68
  59. package/services/earning-service/service.js +1 -0
  60. package/services/swap-service/handler/bittensor-handler.d.ts +21 -0
  61. package/services/swap-service/handler/bittensor-handler.js +189 -0
  62. package/services/swap-service/index.js +7 -0
  63. package/services/transaction-service/index.js +1 -0
  64. package/services/transaction-service/types.d.ts +4 -3
  65. package/types/balance/index.d.ts +3 -1
  66. package/types/balance/index.js +1 -0
  67. package/types/balance/transfer.d.ts +7 -0
  68. package/types/fee/base.d.ts +1 -0
  69. package/types/swap/index.d.ts +3 -1
  70. package/types/swap/index.js +3 -1
  71. package/types/yield/actions/join/step.d.ts +6 -0
  72. package/types/yield/actions/join/submit.d.ts +1 -0
  73. package/utils/fee/transfer.d.ts +1 -0
  74. package/utils/fee/transfer.js +21 -6
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.3.77-0'
10
+ version: '1.3.78-0'
11
11
  };
@@ -1,3 +1,4 @@
1
1
  import { SubscribeEvmPalletBalance } from '@subwallet/extension-base/types';
2
2
  export declare function subscribeERC20Interval({ addresses, assetMap, callback, chainInfo, evmApi }: SubscribeEvmPalletBalance): () => void;
3
+ export declare function subscribeERC20IntervalForSubtensorEvm({ addresses, assetMap, callback, chainInfo, evmApi, substrateApiMap }: SubscribeEvmPalletBalance): () => void;
3
4
  export declare function subscribeEVMBalance(params: SubscribeEvmPalletBalance): () => void;
@@ -5,9 +5,11 @@ import { _AssetType } from '@subwallet/chain-list/types';
5
5
  import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { ASTAR_REFRESH_BALANCE_INTERVAL, SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
7
7
  import { getERC20Contract } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
8
+ import { evmToSs58 } from '@subwallet/extension-base/services/balance-service/transfer/xcm/bittensorBridge/utils';
8
9
  import { _BALANCE_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
9
- import { _getContractAddressOfToken } from '@subwallet/extension-base/services/chain-service/utils';
10
+ import { _getAssetNetuid, _getContractAddressOfToken } from '@subwallet/extension-base/services/chain-service/utils';
10
11
  import { filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
12
+ import BigN from 'bignumber.js';
11
13
  import { BN } from '@polkadot/util';
12
14
  export function subscribeERC20Interval({
13
15
  addresses,
@@ -60,6 +62,77 @@ export function subscribeERC20Interval({
60
62
  clearInterval(interval);
61
63
  };
62
64
  }
65
+ export function subscribeERC20IntervalForSubtensorEvm({
66
+ addresses,
67
+ assetMap,
68
+ callback,
69
+ chainInfo,
70
+ evmApi,
71
+ substrateApiMap
72
+ }) {
73
+ const chain = chainInfo.slug;
74
+ const tokenList = filterAssetsByChainAndType(assetMap, chain, [_AssetType.ERC20]);
75
+ let cancel = false;
76
+ const getTokenBalances = () => {
77
+ Object.values(tokenList).map(async tokenInfo => {
78
+ try {
79
+ var _tokenInfo$metadata;
80
+ if ((_tokenInfo$metadata = tokenInfo.metadata) !== null && _tokenInfo$metadata !== void 0 && _tokenInfo$metadata.isAlphaToken && substrateApiMap) {
81
+ const ss58ToEvmMap = {};
82
+ const subtensorEvmSs58Address = [];
83
+ addresses.forEach(address => {
84
+ const ss58Address = evmToSs58(address);
85
+ subtensorEvmSs58Address.push(ss58Address);
86
+ ss58ToEvmMap[ss58Address] = address;
87
+ });
88
+ if (cancel) {
89
+ return;
90
+ }
91
+ const substrateApi = await substrateApiMap.bittensor.isReady;
92
+ const rawData = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(subtensorEvmSs58Address);
93
+ const values = rawData.toPrimitive();
94
+ const converted = {};
95
+ for (let i = 0; i < values.length; i++) {
96
+ const [, stakes] = values[i];
97
+ const s58Address = subtensorEvmSs58Address[i];
98
+ const address = ss58ToEvmMap[s58Address];
99
+ converted[address] = {};
100
+ stakes.forEach(stakeInfo => {
101
+ const {
102
+ netuid,
103
+ stake
104
+ } = stakeInfo;
105
+ const currentValue = converted[address][netuid] || BigN(0);
106
+ converted[address][netuid] = currentValue.plus(stake);
107
+ });
108
+ }
109
+ const netuid = _getAssetNetuid(tokenInfo);
110
+ const items = Object.entries(converted).map(([address, stakeMap]) => {
111
+ const value = stakeMap[netuid] || BigN(0);
112
+ return {
113
+ address: address,
114
+ tokenSlug: tokenInfo.slug,
115
+ state: APIItemState.READY,
116
+ free: value.toFixed(0),
117
+ locked: '0'
118
+ };
119
+ });
120
+ if (!cancel) {
121
+ callback(items);
122
+ }
123
+ }
124
+ } catch (err) {
125
+ console.log(tokenInfo.slug, err);
126
+ }
127
+ });
128
+ };
129
+ getTokenBalances();
130
+ const interval = setInterval(getTokenBalances, SUB_TOKEN_REFRESH_BALANCE_INTERVAL);
131
+ return () => {
132
+ cancel = true;
133
+ clearInterval(interval);
134
+ };
135
+ }
63
136
  async function getEVMBalance(addresses, web3Api) {
64
137
  return await Promise.all(addresses.map(async address => {
65
138
  try {
@@ -110,8 +183,10 @@ export function subscribeEVMBalance(params) {
110
183
  getBalance();
111
184
  const interval = setInterval(getBalance, ASTAR_REFRESH_BALANCE_INTERVAL);
112
185
  const unsub2 = subscribeERC20Interval(params);
186
+ const unsub3 = subscribeERC20IntervalForSubtensorEvm(params);
113
187
  return () => {
114
188
  clearInterval(interval);
115
189
  unsub2 && unsub2();
190
+ unsub3 && unsub3();
116
191
  };
117
192
  }
@@ -46,7 +46,8 @@ export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _cha
46
46
  assetMap: chainAssetMap,
47
47
  callback,
48
48
  chainInfo,
49
- evmApi
49
+ evmApi,
50
+ substrateApiMap
50
51
  });
51
52
  }
52
53
  const tonApi = tonApiMap[chainSlug];
@@ -207,12 +207,16 @@ export class BalanceService {
207
207
  const bitcoinApiMap = this.state.chainService.getBitcoinApiMap();
208
208
  let unsub = noop;
209
209
  unsub = subscribeBalance([address], [chain], [tSlug], assetMap, chainInfoMap, substrateApiMap, evmApiMap, tonApiMap, cardanoApiMap, bitcoinApiMap, result => {
210
+ var _rs$lockedDetails;
210
211
  const rs = result[0];
211
212
  let value;
212
213
  switch (balanceType) {
213
214
  case BalanceType.TOTAL:
214
215
  value = new BigN(rs.free).plus(new BigN(rs.locked)).toFixed();
215
216
  break;
217
+ case BalanceType.STAKING:
218
+ value = ((_rs$lockedDetails = rs.lockedDetails) === null || _rs$lockedDetails === void 0 ? void 0 : _rs$lockedDetails.staking) || '0';
219
+ break;
216
220
  case BalanceType.TOTAL_MINUS_RESERVED:
217
221
  if (_BALANCE_CHAIN_GROUP.notSupportGetBalanceByType.includes(chainInfo.slug)) {
218
222
  // TODO: Currently Vara and Avail staking from nomination pools is not fully supported.
@@ -220,8 +224,8 @@ export class BalanceService {
220
224
  // Improve later when full staking breakdown is available.
221
225
  value = rs.free;
222
226
  } else {
223
- var _rs$lockedDetails, _rs$lockedDetails2;
224
- value = new BigN(rs.free).plus(new BigN(rs.locked)).minus(BigN.max(new BigN(((_rs$lockedDetails = rs.lockedDetails) === null || _rs$lockedDetails === void 0 ? void 0 : _rs$lockedDetails.reserved) || 0), new BigN(((_rs$lockedDetails2 = rs.lockedDetails) === null || _rs$lockedDetails2 === void 0 ? void 0 : _rs$lockedDetails2.staking) || 0))).toFixed();
227
+ var _rs$lockedDetails2, _rs$lockedDetails3;
228
+ value = new BigN(rs.free).plus(new BigN(rs.locked)).minus(BigN.max(new BigN(((_rs$lockedDetails2 = rs.lockedDetails) === null || _rs$lockedDetails2 === void 0 ? void 0 : _rs$lockedDetails2.reserved) || 0), new BigN(((_rs$lockedDetails3 = rs.lockedDetails) === null || _rs$lockedDetails3 === void 0 ? void 0 : _rs$lockedDetails3.staking) || 0))).toFixed();
225
229
  }
226
230
  break;
227
231
  default:
@@ -10,7 +10,8 @@ interface CreateTransferExtrinsicProps {
10
10
  value: string;
11
11
  transferAll: boolean;
12
12
  tokenInfo: _ChainAsset;
13
+ metadata?: Record<string, any>;
13
14
  }
14
- export declare const createSubstrateExtrinsic: ({ from, networkKey, substrateApi, to, tokenInfo, transferAll, value }: CreateTransferExtrinsicProps) => Promise<[SubmittableExtrinsic | null, string]>;
15
+ export declare const createSubstrateExtrinsic: ({ from, metadata, networkKey, substrateApi, to, tokenInfo, transferAll, value }: CreateTransferExtrinsicProps) => Promise<[SubmittableExtrinsic | null, string]>;
15
16
  export declare const getTransferMockTxFee: (address: string, chainInfo: _ChainInfo, tokenInfo: _ChainAsset, api: _SubstrateApi | _EvmApi | _TonApi) => Promise<BigN>;
16
17
  export {};
@@ -19,6 +19,7 @@ import { BN, u8aToHex } from '@polkadot/util';
19
19
  import { decodeAddress } from '@polkadot/util-crypto';
20
20
  export const createSubstrateExtrinsic = async ({
21
21
  from,
22
+ metadata,
22
23
  networkKey,
23
24
  substrateApi,
24
25
  to,
@@ -121,6 +122,20 @@ export const createSubstrateExtrinsic = async ({
121
122
  }
122
123
  } else if (_TRANSFER_CHAIN_GROUP.truth.includes(networkKey)) {
123
124
  transfer = api.tx.assetManager.transfer(to, _getTokenOnChainInfo(tokenInfo), value);
125
+ } else if (_TRANSFER_CHAIN_GROUP.bittensor.includes(networkKey) && !!metadata) {
126
+ const {
127
+ fromValidator,
128
+ netuid,
129
+ toValidator
130
+ } = metadata;
131
+ const formatToValidator = toValidator === null || toValidator === void 0 ? void 0 : toValidator.split('___')[0];
132
+ if (fromValidator === formatToValidator) {
133
+ transfer = substrateApi.api.tx.subtensorModule.transferStake(to, fromValidator, netuid, netuid, value);
134
+ } else {
135
+ const moveStakeTx = substrateApi.api.tx.subtensorModule.moveStake(fromValidator, formatToValidator, netuid, netuid, value);
136
+ const transferStakeTx = substrateApi.api.tx.subtensorModule.transferStake(to, formatToValidator, netuid, netuid, value);
137
+ transfer = substrateApi.api.tx.utility.batchAll([moveStakeTx, transferStakeTx]);
138
+ }
124
139
  }
125
140
  return [transfer, transferAmount || value];
126
141
  };
@@ -0,0 +1,2 @@
1
+ export * from './nativeTokenBridge';
2
+ export * from './utils';
@@ -0,0 +1,5 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from "./nativeTokenBridge.js";
5
+ export * from "./utils.js";
@@ -0,0 +1,6 @@
1
+ import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
2
+ import { FeeCustom, FeeInfo, FeeOption } from '@subwallet/extension-base/types';
3
+ import { TransactionConfig } from 'web3-core';
4
+ export declare function getSubtensorEvmtoBittensorExtrinsic(sender: string, recipientAddress: string, sendingValue: string, evmApi: _EvmApi, _feeInfo: FeeInfo, feeCustom?: FeeCustom, feeOption?: FeeOption): Promise<TransactionConfig>;
5
+ export declare function _isBittensorToSubtensorBridge(srcChain: string, destChain: string): boolean;
6
+ export declare function _isSubtensorToBittensorBridge(srcChain: string, destChain: string): boolean;
@@ -0,0 +1,50 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
5
+ import { getWeb3Contract } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
6
+ import { combineEthFee } from '@subwallet/extension-base/utils';
7
+ import { BN, compactToU8a, u8aConcat, u8aToHex } from '@polkadot/util';
8
+ import { decodeAddress } from '@polkadot/util-crypto';
9
+ const NATIVE_SUBTENSOR_ABI = [{
10
+ inputs: [{
11
+ internalType: 'bytes32',
12
+ name: 'data',
13
+ type: 'bytes32'
14
+ }],
15
+ name: 'transfer',
16
+ outputs: [],
17
+ stateMutability: 'payable',
18
+ type: 'function'
19
+ }];
20
+ const nativeSubtensorEvmContractAddress = '0x0000000000000000000000000000000000000800';
21
+ export async function getSubtensorEvmtoBittensorExtrinsic(sender, recipientAddress, sendingValue, evmApi, _feeInfo, feeCustom, feeOption) {
22
+ const contract = getWeb3Contract(nativeSubtensorEvmContractAddress, evmApi, NATIVE_SUBTENSOR_ABI);
23
+ const toAccountId = decodeAddress(recipientAddress);
24
+ const amountSubstrate = new BN(sendingValue).div(new BN(10).pow(new BN(9)));
25
+ const amountU8a = compactToU8a(amountSubstrate);
26
+ const scaleEncoded = u8aConcat(toAccountId, amountU8a);
27
+ const dataU8a = scaleEncoded.slice(0, 32);
28
+ const dataHex = u8aToHex(dataU8a);
29
+
30
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
31
+ const transferCall = contract.methods.transfer(dataHex);
32
+ const txData = transferCall.encodeABI();
33
+ const feeInfo = _feeInfo;
34
+ const feeCombine = combineEthFee(feeInfo, feeOption, feeCustom);
35
+ const transactionConfig = {
36
+ from: sender,
37
+ to: nativeSubtensorEvmContractAddress,
38
+ value: sendingValue,
39
+ data: txData,
40
+ ...feeCombine
41
+ };
42
+ transactionConfig.gas = (await evmApi.api.eth.estimateGas(transactionConfig).catch(() => 30000)).toString();
43
+ return transactionConfig;
44
+ }
45
+ export function _isBittensorToSubtensorBridge(srcChain, destChain) {
46
+ return srcChain === COMMON_CHAIN_SLUGS.BITTENSOR && destChain === COMMON_CHAIN_SLUGS.SUBTENSOR_EVM || srcChain === COMMON_CHAIN_SLUGS.BITTENSOR_TESTNET && destChain === COMMON_CHAIN_SLUGS.SUBTENSOR_EVM_TESTNET;
47
+ }
48
+ export function _isSubtensorToBittensorBridge(srcChain, destChain) {
49
+ return srcChain === COMMON_CHAIN_SLUGS.SUBTENSOR_EVM && destChain === COMMON_CHAIN_SLUGS.BITTENSOR || srcChain === COMMON_CHAIN_SLUGS.SUBTENSOR_EVM_TESTNET && destChain === COMMON_CHAIN_SLUGS.BITTENSOR_TESTNET;
50
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Convert an EVM address (0x...) into a Substrate SS58 address
3
+ *
4
+ * @param evmAddress EVM address, with or without the "0x" prefix
5
+ * @param ss58Prefix SS58 network prefix (default is 42 – generic Substrate)
6
+ * @returns SS58-encoded Substrate address
7
+ */
8
+ export declare function evmToSs58(evmAddress: string, ss58Prefix?: number): string;
@@ -0,0 +1,29 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { hexToU8a } from '@polkadot/util';
5
+ import { blake2AsU8a, encodeAddress } from '@polkadot/util-crypto';
6
+ const EVM_PREFIX = new TextEncoder().encode('evm:');
7
+
8
+ /**
9
+ * Convert an EVM address (0x...) into a Substrate SS58 address
10
+ *
11
+ * @param evmAddress EVM address, with or without the "0x" prefix
12
+ * @param ss58Prefix SS58 network prefix (default is 42 – generic Substrate)
13
+ * @returns SS58-encoded Substrate address
14
+ */
15
+ export function evmToSs58(evmAddress, ss58Prefix = 42) {
16
+ // Normalize input: ensure "0x" prefix and convert to Uint8Array
17
+ const addressBytes = hexToU8a(evmAddress.startsWith('0x') ? evmAddress : '0x' + evmAddress);
18
+
19
+ // Build the input buffer: "evm:" prefix + 20-byte EVM address
20
+ const combined = new Uint8Array(EVM_PREFIX.length + addressBytes.length);
21
+ combined.set(EVM_PREFIX);
22
+ combined.set(addressBytes, EVM_PREFIX.length);
23
+
24
+ // Hash using blake2b-256 to derive a Substrate AccountId
25
+ const hash = blake2AsU8a(combined);
26
+
27
+ // Encode the hash into an SS58 address with the given prefix
28
+ return encodeAddress(hash, ss58Prefix);
29
+ }
@@ -1,4 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { GetXcmFeeRequest } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
2
3
  import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
3
4
  import { FeeInfo, TransactionFee } from '@subwallet/extension-base/types';
4
5
  import { TransactionConfig } from 'web3-core';
@@ -14,6 +15,7 @@ export declare type CreateXcmExtrinsicProps = {
14
15
  sendingValue: string;
15
16
  substrateApi?: _SubstrateApi;
16
17
  feeInfo: FeeInfo;
18
+ transferAll?: boolean;
17
19
  } & TransactionFee;
18
20
  export declare type FunctionCreateXcmExtrinsic = (props: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'> | TransactionConfig | undefined>;
19
21
  export declare const createSnowBridgeExtrinsic: ({ destinationChain, evmApi, feeCustom, feeInfo, feeOption, originChain, originTokenInfo, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
@@ -21,6 +23,9 @@ export declare const createAvailBridgeTxFromEth: ({ evmApi, feeCustom, feeInfo,
21
23
  export declare const createAvailBridgeExtrinsicFromAvail: ({ recipient, sendingValue, substrateApi }: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'>>;
22
24
  export declare const createPolygonBridgeExtrinsic: ({ destinationChain, evmApi, feeCustom, feeInfo, feeOption, originChain, originTokenInfo, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
23
25
  export declare const createXcmExtrinsicV2: (request: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'> | undefined>;
26
+ export declare const getMinXcmTransferableAmount: (request: GetXcmFeeRequest) => Promise<string | undefined>;
24
27
  export declare const dryRunXcmExtrinsicV2: (request: CreateXcmExtrinsicProps, isPreview?: boolean) => Promise<boolean>;
25
28
  export declare const getXcmOriginFee: (request: CreateXcmExtrinsicProps) => Promise<string | undefined>;
26
29
  export declare const createAcrossBridgeExtrinsic: ({ destinationChain, destinationTokenInfo, evmApi, feeCustom, feeInfo, feeOption, originChain, originTokenInfo, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
30
+ export declare const createBittensorToSubtensorEvmExtrinsic: ({ destinationChain, originChain, recipient, sendingValue, substrateApi, transferAll }: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'>>;
31
+ export declare const createSubtensorEvmToBittensorExtrinsic: ({ destinationChain, evmApi, feeCustom, feeInfo, feeOption, originChain, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
@@ -1,13 +1,14 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { _isAcrossBridgeXcm, _isPolygonBridgeXcm, _isPosBridgeXcm, _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
4
+ import { _isAcrossBridgeXcm, _isBittensorToSubtensorEvmBridge, _isPolygonBridgeXcm, _isPosBridgeXcm, _isSnowBridgeXcm, _isSubtensorEvmtoBittensorBridge } from '@subwallet/extension-base/core/substrate/xcm-parser';
5
5
  import { getAvailBridgeExtrinsicFromAvail, getAvailBridgeTxFromEth } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
6
6
  import { _createPolygonBridgeL1toL2Extrinsic, _createPolygonBridgeL2toL1Extrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
7
7
  import { getSnowBridgeEvmTransfer } from '@subwallet/extension-base/services/balance-service/transfer/xcm/snowBridge';
8
- import { buildXcm, dryRunPreviewXcm, dryRunXcm, estimateXcmFee, isChainNotSupportDryRun, isChainNotSupportPolkadotApi } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
8
+ import { buildXcm, dryRunPreviewXcm, dryRunXcm, estimateXcmFee, fetchMinXcmTransferableAmount, isChainNotSupportDryRun, isChainNotSupportPolkadotApi } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
9
9
  import { combineEthFee } from '@subwallet/extension-base/utils';
10
10
  import subwalletApiSdk from '@subwallet-monorepos/subwallet-services-sdk';
11
+ import { evmToSs58, getSubtensorEvmtoBittensorExtrinsic } from "./bittensorBridge/index.js";
11
12
  import { _createPosBridgeL1toL2Extrinsic, _createPosBridgeL2toL1Extrinsic } from "./posBridge.js";
12
13
  // SnowBridge
13
14
  export const createSnowBridgeExtrinsic = async ({
@@ -96,6 +97,13 @@ export const createXcmExtrinsicV2 = async request => {
96
97
  return undefined;
97
98
  }
98
99
  };
100
+ export const getMinXcmTransferableAmount = async request => {
101
+ try {
102
+ return await fetchMinXcmTransferableAmount(request);
103
+ } catch (e) {
104
+ return undefined;
105
+ }
106
+ };
99
107
  export const dryRunXcmExtrinsicV2 = async (request, isPreview = false) => {
100
108
  try {
101
109
  const dryRunResult = isPreview ? await dryRunPreviewXcm(request) : await dryRunXcm(request);
@@ -195,4 +203,51 @@ export const createAcrossBridgeExtrinsic = async ({
195
203
  }
196
204
  return Promise.reject(new Error(error === null || error === void 0 ? void 0 : error.message));
197
205
  }
206
+ };
207
+
208
+ // Native bittensor <-> subtensor EVM bridge
209
+
210
+ export const createBittensorToSubtensorEvmExtrinsic = async ({
211
+ destinationChain,
212
+ originChain,
213
+ recipient,
214
+ sendingValue,
215
+ substrateApi,
216
+ transferAll
217
+ }) => {
218
+ if (!_isBittensorToSubtensorEvmBridge(originChain, destinationChain)) {
219
+ throw new Error('This is not a valid Bittensor bridge transfer');
220
+ }
221
+ if (!substrateApi) {
222
+ throw Error('Substrate API is not available');
223
+ }
224
+ const api = substrateApi.api;
225
+ await api.isReady;
226
+ const subtensorEvmAddress = evmToSs58(recipient);
227
+ if (transferAll) {
228
+ return api.tx.balances.transferAll(subtensorEvmAddress, false);
229
+ }
230
+ return api.tx.balances.transferKeepAlive(subtensorEvmAddress, sendingValue);
231
+ };
232
+ export const createSubtensorEvmToBittensorExtrinsic = async ({
233
+ destinationChain,
234
+ evmApi,
235
+ feeCustom,
236
+ feeInfo,
237
+ feeOption,
238
+ originChain,
239
+ recipient,
240
+ sender,
241
+ sendingValue
242
+ }) => {
243
+ if (!_isSubtensorEvmtoBittensorBridge(originChain, destinationChain)) {
244
+ throw new Error('This is not a valid Subtensor EVM bridge transfer');
245
+ }
246
+ if (!evmApi) {
247
+ throw Error('Evm API is not available');
248
+ }
249
+ if (!sender) {
250
+ throw Error('Sender is required');
251
+ }
252
+ return getSubtensorEvmtoBittensorExtrinsic(sender, recipient, sendingValue, evmApi, feeInfo, feeCustom, feeOption);
198
253
  };
@@ -21,7 +21,7 @@ export declare type DryRunResult = {
21
21
  destination?: DryRunNodeResult;
22
22
  hops: THopInfo[];
23
23
  };
24
- interface GetXcmFeeRequest {
24
+ export interface GetXcmFeeRequest {
25
25
  sender: string;
26
26
  recipient: string;
27
27
  value: string;
@@ -44,6 +44,7 @@ export declare function buildXcm(request: CreateXcmExtrinsicProps): Promise<Subm
44
44
  export declare function dryRunXcm(request: CreateXcmExtrinsicProps): Promise<DryRunResult>;
45
45
  export declare function dryRunPreviewXcm(request: CreateXcmExtrinsicProps): Promise<DryRunResult>;
46
46
  export declare function estimateXcmFee(request: GetXcmFeeRequest): Promise<GetXcmFeeResult | undefined>;
47
+ export declare function fetchMinXcmTransferableAmount(request: GetXcmFeeRequest): Promise<string>;
47
48
  export declare function isChainNotSupportPolkadotApi(str: string): boolean;
48
49
  export declare function isChainNotSupportDryRun(str: string): boolean;
49
- export {};
50
+ export declare function isSubstrateCrossChain(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo): boolean;
@@ -2,16 +2,25 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { fetchParaSpellChainMap } from '@subwallet/extension-base/constants/paraspell-chain-map';
5
+ import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
6
+ import { _isAcrossChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
7
+ import { isAvailChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
8
+ import { _isPolygonChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
9
+ import { _isPosChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge';
10
+ import { _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
5
11
  import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
6
12
  import { fetchFromProxyService } from '@subwallet/extension-base/utils';
7
13
  import BigNumber from 'bignumber.js';
8
14
  import { assert, compactToU8a, isHex, u8aConcat, u8aEq } from '@polkadot/util';
15
+ import { _isBittensorToSubtensorBridge, _isSubtensorToBittensorBridge } from "./bittensorBridge/index.js";
9
16
  const version = '/v5';
10
17
  const paraSpellApi = {
11
18
  buildXcm: `${version}/x-transfer`,
12
19
  feeXcm: `${version}/xcm-fee`,
13
20
  dryRunXcm: `${version}/dry-run`,
14
- dryRunPreviewXcm: `${version}/dry-run-preview`
21
+ dryRunPreviewXcm: `${version}/dry-run-preview`,
22
+ maxTransferable: `${version}/transferable-amount`,
23
+ minTransferable: `${version}/min-transferable-amount`
15
24
  };
16
25
  function txHexToSubmittableExtrinsic(api, hex) {
17
26
  try {
@@ -240,6 +249,41 @@ export async function estimateXcmFee(request) {
240
249
  }
241
250
  return await response.json();
242
251
  }
252
+ export async function fetchMinXcmTransferableAmount(request) {
253
+ var _originTokenInfo$meta4;
254
+ const {
255
+ fromChainInfo: originChain,
256
+ fromTokenInfo: originTokenInfo,
257
+ recipient,
258
+ sender,
259
+ toChainInfo: destinationChain,
260
+ value: sendingValue
261
+ } = request;
262
+ const paraSpellChainMap = await fetchParaSpellChainMap();
263
+ const paraSpellIdentifyV4 = (_originTokenInfo$meta4 = originTokenInfo.metadata) === null || _originTokenInfo$meta4 === void 0 ? void 0 : _originTokenInfo$meta4.paraSpellIdentifyV4;
264
+ if (!paraSpellIdentifyV4) {
265
+ throw new Error('Token is not support XCM at this time');
266
+ }
267
+ const bodyData = {
268
+ senderAddress: sender,
269
+ address: recipient,
270
+ from: paraSpellChainMap[originChain.slug],
271
+ to: paraSpellChainMap[destinationChain.slug],
272
+ currency: createParaSpellCurrency(paraSpellIdentifyV4, sendingValue),
273
+ options: {
274
+ abstractDecimals: false
275
+ }
276
+ };
277
+ const response = await fetchFromProxyService(ProxyServiceRoute.PARASPELL, paraSpellApi.minTransferable, {
278
+ method: 'POST',
279
+ body: JSON.stringify(bodyData),
280
+ headers: {
281
+ 'Content-Type': 'application/json',
282
+ Accept: 'application/json'
283
+ }
284
+ });
285
+ return await response.json();
286
+ }
243
287
  function createParaSpellCurrency(paraSpellIdentifyV4, amount) {
244
288
  return {
245
289
  ...paraSpellIdentifyV4,
@@ -255,4 +299,46 @@ export function isChainNotSupportDryRun(str) {
255
299
  const regex = /(?=.*DryRunApi)(?=.*not available).*/i; // Example: DryRunApi is not available on node Acala
256
300
 
257
301
  return regex.test(str);
302
+ }
303
+ export function isSubstrateCrossChain(originChainInfo, destinationChainInfo) {
304
+ if (originChainInfo.slug === destinationChainInfo.slug) {
305
+ return false;
306
+ }
307
+
308
+ // isAvailBridgeFromEvm
309
+ if (_isPureEvmChain(originChainInfo) && isAvailChainBridge(destinationChainInfo.slug)) {
310
+ return false;
311
+ }
312
+
313
+ // isAvailBridgeFromAvail
314
+ if (isAvailChainBridge(originChainInfo.slug) && _isPureEvmChain(destinationChainInfo)) {
315
+ return false;
316
+ }
317
+
318
+ // isSnowBridgeEvmTransfer
319
+ if (_isPureEvmChain(originChainInfo) && _isSnowBridgeXcm(originChainInfo, destinationChainInfo)) {
320
+ return false;
321
+ }
322
+
323
+ // isPolygonBridgeTransfer
324
+ if (_isPolygonChainBridge(originChainInfo.slug, destinationChainInfo.slug)) {
325
+ return false;
326
+ }
327
+
328
+ // isPosBridgeTransfer
329
+ if (_isPosChainBridge(originChainInfo.slug, destinationChainInfo.slug)) {
330
+ return false;
331
+ }
332
+
333
+ // isAcrossBridgeTransfer
334
+ if (_isAcrossChainBridge(originChainInfo.slug, destinationChainInfo.slug)) {
335
+ return false;
336
+ }
337
+ if (_isBittensorToSubtensorBridge(originChainInfo.slug, destinationChainInfo.slug)) {
338
+ return false;
339
+ }
340
+ if (_isSubtensorToBittensorBridge(originChainInfo.slug, destinationChainInfo.slug)) {
341
+ return false;
342
+ }
343
+ return true;
258
344
  }
@@ -30,6 +30,7 @@ export declare const _BALANCE_CHAIN_GROUP: {
30
30
  bittensor: string[];
31
31
  moonbeam: string[];
32
32
  notSupportGetBalanceByType: string[];
33
+ subtensor_evm: string[];
33
34
  };
34
35
  export declare const _BALANCE_LOCKED_ID_GROUP: {
35
36
  staking: string[];
@@ -81,6 +82,7 @@ export declare const _TRANSFER_CHAIN_GROUP: {
81
82
  centrifuge: string[];
82
83
  disable_transfer: string[];
83
84
  truth: string[];
85
+ bittensor: string[];
84
86
  };
85
87
  export declare const USE_MULTILOCATION_INDEX: string[];
86
88
  export declare const _MANTA_ZK_CHAIN_GROUP: string[];
@@ -43,7 +43,8 @@ export const _BALANCE_CHAIN_GROUP = {
43
43
  supportBridged: ['rococo_assethub', 'statemint', 'statemine', 'polimec'],
44
44
  bittensor: ['bittensor', 'bittensor_testnet'],
45
45
  moonbeam: ['moonbeam', 'moonriver', 'moonbase'],
46
- notSupportGetBalanceByType: ['vara_network', 'vara_testnet', 'availTuringTest', 'avail_mainnet']
46
+ notSupportGetBalanceByType: ['vara_network', 'vara_testnet', 'availTuringTest', 'avail_mainnet'],
47
+ subtensor_evm: ['subtensor_evm']
47
48
  };
48
49
  export const _BALANCE_LOCKED_ID_GROUP = {
49
50
  staking: ['staking', 'delegatedStaking', 'pooledStaking', 'stkngdel', 'stk_stks', 'dappStaking', 'parachainStaking', 'appstakeappstake', 'collatorStaking'],
@@ -296,7 +297,8 @@ export const _TRANSFER_CHAIN_GROUP = {
296
297
  pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot', 'jamton', 'hydradx_hollarnet'],
297
298
  centrifuge: ['centrifuge'],
298
299
  disable_transfer: ['crab', 'pangolin'],
299
- truth: ['truth_network']
300
+ truth: ['truth_network'],
301
+ bittensor: ['bittensor', 'bittensor_testnet']
300
302
  };
301
303
  export const USE_MULTILOCATION_INDEX = ['energy_web_x'];
302
304
  export const _MANTA_ZK_CHAIN_GROUP = ['calamari'];
@@ -1,5 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
2
- export declare const ChainListVersion = "0.2.126";
2
+ export declare const ChainListVersion = "0.2.127";
3
3
  export interface PatchInfo {
4
4
  patchVersion: string;
5
5
  appliedVersion: string;
@@ -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 = process.env.PATCH_CHAIN_LIST_URL || (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
- export const ChainListVersion = '0.2.126'; // update this when build chain-list
8
+ export const ChainListVersion = '0.2.127'; // update this when build chain-list
9
9
 
10
10
  // todo: move this interface to chainlist
11
11
 
@@ -26,3 +26,4 @@ export declare const MANTA_VALIDATOR_POINTS_PER_BLOCK = 20;
26
26
  export declare const MANTA_MIN_DELEGATION = 500;
27
27
  export declare const CHANNEL_ID = 7;
28
28
  export declare const STAKING_IDENTITY_API_SLUG: Record<string, string>;
29
+ export declare const MIN_XCM_LIQUID_STAKING_DOT = "15000000000";
@@ -36,4 +36,5 @@ export const CHANNEL_ID = 7;
36
36
  export const STAKING_IDENTITY_API_SLUG = {
37
37
  statemine: 'peopleKusama',
38
38
  statemint: 'polkadot_people'
39
- };
39
+ };
40
+ export const MIN_XCM_LIQUID_STAKING_DOT = '15000000000';
@@ -55,7 +55,7 @@ export default abstract class BaseSpecialStakingPoolHandler extends BasePoolHand
55
55
  protected validateJoinStep(id: number, params: OptimalYieldPathParams, path: OptimalYieldPath, bnInputTokenBalance: BN, isXcmOk: boolean): Promise<TransactionError[]>;
56
56
  validateYieldJoin(params: SubmitYieldJoinData, path: OptimalYieldPath): Promise<TransactionError[]>;
57
57
  protected handleTokenApproveStep(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<HandleYieldStepData>;
58
- handleXcmStep(data: SubmitYieldJoinData, path: OptimalYieldPath, xcmFee: string): Promise<HandleYieldStepData>;
58
+ handleXcmStep(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<HandleYieldStepData>;
59
59
  abstract handleSubmitStep(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<HandleYieldStepData>;
60
60
  handleYieldJoin(data: SubmitYieldJoinData, path: OptimalYieldPath, currentStep: number): Promise<HandleYieldStepData>;
61
61
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;