@subwallet/extension-base 1.3.2-0 → 1.3.4-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +13 -0
- package/background/KoniTypes.js +1 -0
- package/cjs/background/KoniTypes.js +1 -0
- package/cjs/constants/blocked-actions-list.js +1 -2
- package/cjs/constants/index.js +16 -1
- package/cjs/constants/remind-notification-time.js +14 -0
- package/cjs/core/logic-validation/transfer.js +12 -6
- package/cjs/core/substrate/xcm-parser.js +13 -1
- package/cjs/koni/api/contract-handler/utils/index.js +20 -1
- package/cjs/koni/api/nft/assethub_nft/index.js +30 -7
- package/cjs/koni/background/handlers/Extension.js +110 -23
- package/cjs/koni/background/handlers/State.js +5 -2
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/process.js +2 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +11 -12
- package/cjs/services/balance-service/transfer/xcm/availBridge.js +198 -0
- package/cjs/services/balance-service/transfer/xcm/index.js +50 -5
- package/cjs/services/chain-service/handler/EvmApi.js +12 -21
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +29 -0
- package/cjs/services/chain-service/index.js +44 -13
- package/cjs/services/chain-service/utils/index.js +20 -0
- package/cjs/services/earning-service/handlers/base.js +14 -4
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +10 -2
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +2 -0
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +2 -0
- package/cjs/services/earning-service/handlers/native-staking/tao.js +25 -38
- package/cjs/services/earning-service/handlers/nomination-pool/index.js +9 -4
- package/cjs/services/earning-service/service.js +5 -0
- package/cjs/services/earning-service/utils/index.js +0 -11
- package/cjs/services/inapp-notification-service/consts.js +31 -0
- package/cjs/services/inapp-notification-service/index.js +260 -0
- package/cjs/services/inapp-notification-service/interfaces.js +32 -0
- package/cjs/services/inapp-notification-service/utils.js +197 -0
- package/cjs/services/keyring-service/context/account-context.js +9 -0
- package/cjs/services/keyring-service/context/state.js +4 -0
- package/cjs/services/setting-service/SettingService.js +9 -1
- package/cjs/services/setting-service/constants.js +16 -1
- package/cjs/services/storage-service/DatabaseService.js +42 -3
- package/cjs/services/storage-service/databases/index.js +3 -0
- package/cjs/services/storage-service/db-stores/InappNotification.js +81 -0
- package/cjs/services/transaction-service/index.js +13 -0
- package/cjs/services/transaction-service/utils.js +3 -0
- package/cjs/types/avail-bridge/index.js +1 -0
- package/cjs/types/notification/index.js +1 -0
- package/cjs/utils/account/transform.js +9 -5
- package/cjs/utils/staticData/index.js +7 -2
- package/constants/blocked-actions-list.js +1 -2
- package/constants/index.d.ts +2 -0
- package/constants/index.js +3 -1
- package/constants/remind-notification-time.d.ts +2 -0
- package/constants/remind-notification-time.js +7 -0
- package/core/logic-validation/transfer.js +12 -6
- package/core/substrate/xcm-parser.d.ts +1 -0
- package/core/substrate/xcm-parser.js +12 -1
- package/koni/api/contract-handler/utils/avail_bridge_abi.json +1659 -0
- package/koni/api/contract-handler/utils/avail_test_bridge_abi.json +1692 -0
- package/koni/api/contract-handler/utils/index.d.ts +4 -0
- package/koni/api/contract-handler/utils/index.js +15 -0
- package/koni/api/nft/assethub_nft/index.d.ts +2 -0
- package/koni/api/nft/assethub_nft/index.js +30 -7
- package/koni/background/handlers/Extension.d.ts +7 -0
- package/koni/background/handlers/Extension.js +112 -25
- package/koni/background/handlers/State.d.ts +2 -0
- package/koni/background/handlers/State.js +5 -2
- package/package.json +54 -6
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/process.js +2 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +5 -6
- package/services/balance-service/transfer/xcm/availBridge.d.ts +45 -0
- package/services/balance-service/transfer/xcm/availBridge.js +186 -0
- package/services/balance-service/transfer/xcm/index.d.ts +8 -8
- package/services/balance-service/transfer/xcm/index.js +46 -5
- package/services/chain-service/handler/EvmApi.js +12 -21
- package/services/chain-service/handler/SubstrateChainHandler.d.ts +2 -0
- package/services/chain-service/handler/SubstrateChainHandler.js +29 -0
- package/services/chain-service/index.d.ts +2 -0
- package/services/chain-service/index.js +45 -14
- package/services/chain-service/types.d.ts +2 -1
- package/services/chain-service/utils/index.d.ts +3 -0
- package/services/chain-service/utils/index.js +14 -0
- package/services/earning-service/handlers/base.d.ts +2 -0
- package/services/earning-service/handlers/base.js +11 -1
- package/services/earning-service/handlers/native-staking/amplitude.js +10 -2
- package/services/earning-service/handlers/native-staking/para-chain.js +2 -0
- package/services/earning-service/handlers/native-staking/relay-chain.js +2 -0
- package/services/earning-service/handlers/native-staking/tao.d.ts +15 -11
- package/services/earning-service/handlers/native-staking/tao.js +21 -38
- package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -1
- package/services/earning-service/handlers/nomination-pool/index.js +9 -4
- package/services/earning-service/service.d.ts +2 -0
- package/services/earning-service/service.js +5 -0
- package/services/earning-service/utils/index.d.ts +0 -2
- package/services/earning-service/utils/index.js +0 -10
- package/services/inapp-notification-service/consts.d.ts +18 -0
- package/services/inapp-notification-service/consts.js +22 -0
- package/services/inapp-notification-service/index.d.ts +37 -0
- package/services/inapp-notification-service/index.js +252 -0
- package/services/inapp-notification-service/interfaces.d.ts +77 -0
- package/services/inapp-notification-service/interfaces.js +24 -0
- package/services/inapp-notification-service/utils.d.ts +55 -0
- package/services/inapp-notification-service/utils.js +173 -0
- package/services/keyring-service/context/account-context.d.ts +3 -0
- package/services/keyring-service/context/account-context.js +9 -0
- package/services/keyring-service/context/state.d.ts +1 -0
- package/services/keyring-service/context/state.js +4 -0
- package/services/setting-service/SettingService.js +9 -1
- package/services/setting-service/constants.d.ts +2 -0
- package/services/setting-service/constants.js +15 -0
- package/services/storage-service/DatabaseService.d.ts +15 -0
- package/services/storage-service/DatabaseService.js +42 -3
- package/services/storage-service/databases/index.d.ts +2 -0
- package/services/storage-service/databases/index.js +3 -0
- package/services/storage-service/db-stores/InappNotification.d.ts +14 -0
- package/services/storage-service/db-stores/InappNotification.js +73 -0
- package/services/transaction-service/index.js +13 -0
- package/services/transaction-service/utils.js +3 -0
- package/types/avail-bridge/index.d.ts +6 -0
- package/types/avail-bridge/index.js +1 -0
- package/types/notification/index.d.ts +9 -0
- package/types/notification/index.js +1 -0
- package/utils/account/transform.js +9 -5
- package/utils/staticData/index.d.ts +5 -1
- package/utils/staticData/index.js +5 -2
- package/utils/staticData/remindNotificationTime.json +1 -0
|
@@ -0,0 +1,186 @@
|
|
|
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 { _AVAIL_BRIDGE_GATEWAY_ABI, _AVAIL_TEST_BRIDGE_GATEWAY_ABI, getAvailBridgeGatewayContract } from '@subwallet/extension-base/koni/api/contract-handler/utils';
|
|
7
|
+
import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
|
|
8
|
+
import { AVAIL_BRIDGE_API } from '@subwallet/extension-base/services/inapp-notification-service/utils';
|
|
9
|
+
import { decodeAddress } from '@subwallet/keyring';
|
|
10
|
+
import { u8aToHex } from '@polkadot/util';
|
|
11
|
+
export const AvailBridgeConfig = {
|
|
12
|
+
ASSET_ID: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
13
|
+
ETHEREUM_DOMAIN: 2,
|
|
14
|
+
// todo: check if these config can change later
|
|
15
|
+
AVAIL_DOMAIN: 1
|
|
16
|
+
};
|
|
17
|
+
export async function getAvailBridgeTxFromEth(originChainInfo, sender, recipient, value, evmApi) {
|
|
18
|
+
var _priority$maxFeePerGa, _priority$maxPriority;
|
|
19
|
+
const availBridgeContractAddress = getAvailBridgeGatewayContract(originChainInfo.slug);
|
|
20
|
+
const ABI = getAvailBridgeAbi(originChainInfo.slug);
|
|
21
|
+
const availBridgeContract = getWeb3Contract(availBridgeContractAddress, evmApi, ABI);
|
|
22
|
+
const _address = u8aToHex(decodeAddress(recipient));
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
24
|
+
const sendAvail = availBridgeContract.methods.sendAVAIL(_address, value);
|
|
25
|
+
const transferData = sendAvail.encodeABI();
|
|
26
|
+
const priority = await calculateGasFeeParams(evmApi, evmApi.chainSlug);
|
|
27
|
+
const gasLimit = await sendAvail.estimateGas({
|
|
28
|
+
from: sender
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
from: sender,
|
|
32
|
+
to: availBridgeContractAddress,
|
|
33
|
+
value: '0',
|
|
34
|
+
data: transferData,
|
|
35
|
+
gasPrice: priority.gasPrice,
|
|
36
|
+
maxFeePerGas: (_priority$maxFeePerGa = priority.maxFeePerGas) === null || _priority$maxFeePerGa === void 0 ? void 0 : _priority$maxFeePerGa.toString(),
|
|
37
|
+
maxPriorityFeePerGas: (_priority$maxPriority = priority.maxPriorityFeePerGas) === null || _priority$maxPriority === void 0 ? void 0 : _priority$maxPriority.toString(),
|
|
38
|
+
gas: gasLimit
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function getAvailBridgeExtrinsicFromAvail(recipient, sendingValue, substrateApi) {
|
|
42
|
+
const data = {
|
|
43
|
+
message: {
|
|
44
|
+
FungibleToken: {
|
|
45
|
+
assetId: AvailBridgeConfig.ASSET_ID,
|
|
46
|
+
amount: BigInt(sendingValue)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
to: `${recipient.padEnd(66, '0')}`,
|
|
50
|
+
domain: AvailBridgeConfig.ETHEREUM_DOMAIN
|
|
51
|
+
};
|
|
52
|
+
const chainApi = await substrateApi.isReady;
|
|
53
|
+
return chainApi.api.tx.vector.sendMessage(data.message, data.to, data.domain);
|
|
54
|
+
}
|
|
55
|
+
export async function getClaimTxOnAvail(notification, substrateApi) {
|
|
56
|
+
const chainApi = await substrateApi.isReady;
|
|
57
|
+
const chainSlug = chainApi.chainSlug;
|
|
58
|
+
const metadata = notification.metadata;
|
|
59
|
+
const lastestEthHeadSlot = await getLastestEthHeadSlot(chainSlug);
|
|
60
|
+
const lastestBlockHash = await getLastestBlockHash(chainSlug, lastestEthHeadSlot);
|
|
61
|
+
const proof = await getClaimProofOnAvail(chainSlug, lastestBlockHash, metadata.messageId);
|
|
62
|
+
return chainApi.api.tx.vector.execute(lastestEthHeadSlot, getAddressMessage(notification), proof.accountProof, proof.storageProof);
|
|
63
|
+
}
|
|
64
|
+
async function getLastestEthHeadSlot(chainSlug) {
|
|
65
|
+
try {
|
|
66
|
+
const api = getAvailBridgeApi(chainSlug);
|
|
67
|
+
const rawResponse = await fetch(`${api}/eth/head`);
|
|
68
|
+
const response = await rawResponse.json();
|
|
69
|
+
return response.slot;
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
throw e;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function getLastestBlockHash(chainSlug, slot) {
|
|
76
|
+
try {
|
|
77
|
+
const api = getAvailBridgeApi(chainSlug);
|
|
78
|
+
const rawResponse = await fetch(`${api}/beacon/slot/${slot}`);
|
|
79
|
+
const response = await rawResponse.json();
|
|
80
|
+
return response.blockHash;
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.error(e);
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function getClaimProofOnAvail(chainSlug, blockHash, messageId) {
|
|
87
|
+
try {
|
|
88
|
+
const api = getAvailBridgeApi(chainSlug);
|
|
89
|
+
const rawResponse = await fetch(`${api}/avl/proof/${blockHash}/${messageId}`);
|
|
90
|
+
return await rawResponse.json();
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.error(e);
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function getClaimProofOnEthereum(chainSlug, blockHash, transactionIndex) {
|
|
97
|
+
try {
|
|
98
|
+
const api = getAvailBridgeApi(chainSlug);
|
|
99
|
+
const rawResponse = await fetch(`${api}/eth/proof/${blockHash}?index=${transactionIndex}`);
|
|
100
|
+
return await rawResponse.json();
|
|
101
|
+
} catch (e) {
|
|
102
|
+
console.error(e);
|
|
103
|
+
throw e;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function getAvailBridgeApi(chainSlug) {
|
|
107
|
+
if (chainSlug === 'avail_mainnet' || chainSlug === COMMON_CHAIN_SLUGS.ETHEREUM) {
|
|
108
|
+
// todo: add COMMON_CHAIN_SLUGS for AVAIL, AVAIL TURING
|
|
109
|
+
return AVAIL_BRIDGE_API.AVAIL_MAINNET;
|
|
110
|
+
}
|
|
111
|
+
return AVAIL_BRIDGE_API.AVAIL_TESTNET;
|
|
112
|
+
}
|
|
113
|
+
export async function getClaimTxOnEthereum(chainSlug, notification, evmApi) {
|
|
114
|
+
var _priority$maxFeePerGa2, _priority$maxPriority2;
|
|
115
|
+
const availBridgeContractAddress = getAvailBridgeGatewayContract(chainSlug);
|
|
116
|
+
const ABI = getAvailBridgeAbi(chainSlug);
|
|
117
|
+
const availBridgeContract = getWeb3Contract(availBridgeContractAddress, evmApi, ABI);
|
|
118
|
+
const metadata = notification.metadata;
|
|
119
|
+
const merkleProof = await getClaimProofOnEthereum(chainSlug, metadata.sourceBlockHash, metadata.sourceTransactionIndex);
|
|
120
|
+
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
122
|
+
const transfer = availBridgeContract.methods.receiveAVAIL({
|
|
123
|
+
messageType: '0x02',
|
|
124
|
+
from: merkleProof.message.from,
|
|
125
|
+
to: merkleProof.message.to,
|
|
126
|
+
originDomain: merkleProof.message.originDomain,
|
|
127
|
+
destinationDomain: merkleProof.message.destinationDomain,
|
|
128
|
+
data: evmApi.api.eth.abi.encodeParameters([{
|
|
129
|
+
name: 'assetId',
|
|
130
|
+
type: 'bytes32'
|
|
131
|
+
}, {
|
|
132
|
+
name: 'amount',
|
|
133
|
+
type: 'uint256'
|
|
134
|
+
}], [merkleProof.message.message.fungibleToken.asset_id, BigInt(merkleProof.message.message.fungibleToken.amount)]),
|
|
135
|
+
messageId: merkleProof.message.id
|
|
136
|
+
}, {
|
|
137
|
+
dataRootProof: merkleProof.dataRootProof,
|
|
138
|
+
leafProof: merkleProof.leafProof,
|
|
139
|
+
rangeHash: merkleProof.rangeHash,
|
|
140
|
+
dataRootIndex: merkleProof.dataRootIndex,
|
|
141
|
+
blobRoot: merkleProof.blobRoot,
|
|
142
|
+
bridgeRoot: merkleProof.bridgeRoot,
|
|
143
|
+
leaf: merkleProof.leaf,
|
|
144
|
+
leafIndex: merkleProof.leafIndex
|
|
145
|
+
});
|
|
146
|
+
const transferData = transfer.encodeABI();
|
|
147
|
+
const gasLimit = await transfer.estimateGas({
|
|
148
|
+
from: metadata.receiverAddress
|
|
149
|
+
});
|
|
150
|
+
const priority = await calculateGasFeeParams(evmApi, evmApi.chainSlug);
|
|
151
|
+
return {
|
|
152
|
+
from: metadata.receiverAddress,
|
|
153
|
+
to: availBridgeContractAddress,
|
|
154
|
+
value: '0',
|
|
155
|
+
data: transferData,
|
|
156
|
+
gasPrice: priority.gasPrice,
|
|
157
|
+
maxFeePerGas: (_priority$maxFeePerGa2 = priority.maxFeePerGas) === null || _priority$maxFeePerGa2 === void 0 ? void 0 : _priority$maxFeePerGa2.toString(),
|
|
158
|
+
maxPriorityFeePerGas: (_priority$maxPriority2 = priority.maxPriorityFeePerGas) === null || _priority$maxPriority2 === void 0 ? void 0 : _priority$maxPriority2.toString(),
|
|
159
|
+
gas: gasLimit
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function getAddressMessage(notification) {
|
|
163
|
+
const metadata = notification.metadata;
|
|
164
|
+
return {
|
|
165
|
+
message: {
|
|
166
|
+
FungibleToken: {
|
|
167
|
+
assetId: AvailBridgeConfig.ASSET_ID,
|
|
168
|
+
amount: metadata.amount
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
from: `${metadata.depositorAddress.padEnd(66, '0')}`,
|
|
172
|
+
to: u8aToHex(decodeAddress(metadata.receiverAddress)),
|
|
173
|
+
originDomain: AvailBridgeConfig.ETHEREUM_DOMAIN,
|
|
174
|
+
destinationDomain: AvailBridgeConfig.AVAIL_DOMAIN,
|
|
175
|
+
id: metadata.messageId
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function getAvailBridgeAbi(chainSlug) {
|
|
179
|
+
if (chainSlug === COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA) {
|
|
180
|
+
return _AVAIL_TEST_BRIDGE_GATEWAY_ABI;
|
|
181
|
+
}
|
|
182
|
+
return _AVAIL_BRIDGE_GATEWAY_ABI;
|
|
183
|
+
}
|
|
184
|
+
export function isAvailChainBridge(chainSlug) {
|
|
185
|
+
return ['avail_mainnet', 'availTuringTest'].includes(chainSlug);
|
|
186
|
+
}
|
|
@@ -3,19 +3,19 @@ import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain
|
|
|
3
3
|
import BigN from 'bignumber.js';
|
|
4
4
|
import { TransactionConfig } from 'web3-core';
|
|
5
5
|
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
|
6
|
-
declare type CreateXcmExtrinsicProps = {
|
|
6
|
+
export declare type CreateXcmExtrinsicProps = {
|
|
7
7
|
originTokenInfo: _ChainAsset;
|
|
8
8
|
destinationTokenInfo: _ChainAsset;
|
|
9
9
|
recipient: string;
|
|
10
10
|
sendingValue: string;
|
|
11
|
-
|
|
11
|
+
evmApi?: _EvmApi;
|
|
12
|
+
substrateApi?: _SubstrateApi;
|
|
12
13
|
chainInfoMap: Record<string, _ChainInfo>;
|
|
14
|
+
sender?: string;
|
|
13
15
|
};
|
|
14
|
-
declare type
|
|
15
|
-
|
|
16
|
-
sender: string;
|
|
17
|
-
};
|
|
18
|
-
export declare const createSnowBridgeExtrinsic: ({ chainInfoMap, destinationTokenInfo, evmApi, originTokenInfo, recipient, sender, sendingValue }: CreateSnowBridgeExtrinsicProps) => Promise<TransactionConfig>;
|
|
16
|
+
export declare type FunctionCreateXcmExtrinsic = (props: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'> | TransactionConfig>;
|
|
17
|
+
export declare const createSnowBridgeExtrinsic: ({ chainInfoMap, destinationTokenInfo, evmApi, originTokenInfo, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
|
|
19
18
|
export declare const createXcmExtrinsic: ({ chainInfoMap, destinationTokenInfo, originTokenInfo, recipient, sendingValue, substrateApi }: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'>>;
|
|
19
|
+
export declare const createAvailBridgeTxFromEth: ({ chainInfoMap, evmApi, originTokenInfo, recipient, sender, sendingValue }: CreateXcmExtrinsicProps) => Promise<TransactionConfig>;
|
|
20
|
+
export declare const createAvailBridgeExtrinsicFromAvail: ({ recipient, sendingValue, substrateApi }: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'>>;
|
|
20
21
|
export declare const getXcmMockTxFee: (substrateApi: _SubstrateApi, chainInfoMap: Record<string, _ChainInfo>, originTokenInfo: _ChainAsset, destinationTokenInfo: _ChainAsset) => Promise<BigN>;
|
|
21
|
-
export {};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
|
|
5
|
+
import { getAvailBridgeExtrinsicFromAvail, getAvailBridgeTxFromEth } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
|
|
5
6
|
import { getExtrinsicByPolkadotXcmPallet } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polkadotXcm';
|
|
6
7
|
import { getSnowBridgeEvmTransfer } from '@subwallet/extension-base/services/balance-service/transfer/xcm/snowBridge';
|
|
7
8
|
import { getExtrinsicByXcmPalletPallet } from '@subwallet/extension-base/services/balance-service/transfer/xcm/xcmPallet';
|
|
@@ -10,7 +11,7 @@ import { _XCM_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-servi
|
|
|
10
11
|
import { _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
11
12
|
import BigN from 'bignumber.js';
|
|
12
13
|
import { u8aToHex } from '@polkadot/util';
|
|
13
|
-
import { addressToEvm
|
|
14
|
+
import { addressToEvm } from '@polkadot/util-crypto';
|
|
14
15
|
export const createSnowBridgeExtrinsic = async ({
|
|
15
16
|
chainInfoMap,
|
|
16
17
|
destinationTokenInfo,
|
|
@@ -25,6 +26,12 @@ export const createSnowBridgeExtrinsic = async ({
|
|
|
25
26
|
if (!_isSnowBridgeXcm(originChainInfo, destinationChainInfo)) {
|
|
26
27
|
throw new Error('This is not a valid SnowBridge transfer');
|
|
27
28
|
}
|
|
29
|
+
if (!evmApi) {
|
|
30
|
+
throw Error('Evm API is not available');
|
|
31
|
+
}
|
|
32
|
+
if (!sender) {
|
|
33
|
+
throw Error('Sender is required');
|
|
34
|
+
}
|
|
28
35
|
return getSnowBridgeEvmTransfer(originTokenInfo, originChainInfo, destinationChainInfo, sender, recipient, sendingValue, evmApi);
|
|
29
36
|
};
|
|
30
37
|
export const createXcmExtrinsic = async ({
|
|
@@ -37,6 +44,9 @@ export const createXcmExtrinsic = async ({
|
|
|
37
44
|
}) => {
|
|
38
45
|
const originChainInfo = chainInfoMap[originTokenInfo.originChain];
|
|
39
46
|
const destinationChainInfo = chainInfoMap[destinationTokenInfo.originChain];
|
|
47
|
+
if (!substrateApi) {
|
|
48
|
+
throw Error('Substrate API is not available');
|
|
49
|
+
}
|
|
40
50
|
const chainApi = await substrateApi.isReady;
|
|
41
51
|
const api = chainApi.api;
|
|
42
52
|
const polkadotXcmSpecialCases = _XCM_CHAIN_GROUP.polkadotXcmSpecialCases.includes(originChainInfo.slug) && _isNativeToken(originTokenInfo);
|
|
@@ -48,24 +58,55 @@ export const createXcmExtrinsic = async ({
|
|
|
48
58
|
}
|
|
49
59
|
return getExtrinsicByXtokensPallet(originTokenInfo, originChainInfo, destinationChainInfo, recipient, sendingValue, api);
|
|
50
60
|
};
|
|
61
|
+
export const createAvailBridgeTxFromEth = ({
|
|
62
|
+
chainInfoMap,
|
|
63
|
+
evmApi,
|
|
64
|
+
originTokenInfo,
|
|
65
|
+
recipient,
|
|
66
|
+
sender,
|
|
67
|
+
sendingValue
|
|
68
|
+
}) => {
|
|
69
|
+
const originChainInfo = chainInfoMap[originTokenInfo.originChain];
|
|
70
|
+
if (!evmApi) {
|
|
71
|
+
throw Error('Evm API is not available');
|
|
72
|
+
}
|
|
73
|
+
if (!sender) {
|
|
74
|
+
throw Error('Sender is required');
|
|
75
|
+
}
|
|
76
|
+
return getAvailBridgeTxFromEth(originChainInfo, sender, recipient, sendingValue, evmApi);
|
|
77
|
+
};
|
|
78
|
+
export const createAvailBridgeExtrinsicFromAvail = async ({
|
|
79
|
+
recipient,
|
|
80
|
+
sendingValue,
|
|
81
|
+
substrateApi
|
|
82
|
+
}) => {
|
|
83
|
+
if (!substrateApi) {
|
|
84
|
+
throw Error('Substrate API is not available');
|
|
85
|
+
}
|
|
86
|
+
return await getAvailBridgeExtrinsicFromAvail(recipient, sendingValue, substrateApi);
|
|
87
|
+
};
|
|
51
88
|
export const getXcmMockTxFee = async (substrateApi, chainInfoMap, originTokenInfo, destinationTokenInfo) => {
|
|
52
89
|
try {
|
|
53
90
|
var _paymentInfo$partialF;
|
|
54
91
|
const destChainInfo = chainInfoMap[destinationTokenInfo.originChain];
|
|
55
92
|
const originChainInfo = chainInfoMap[originTokenInfo.originChain];
|
|
56
|
-
const
|
|
93
|
+
const fakeAddress = '5DRewsYzhJqZXU3SRaWy1FSt5iDr875ao91aw5fjrJmDG4Ap'; // todo: move this
|
|
94
|
+
const substrateAddress = fakeAddress; // todo: move this
|
|
95
|
+
const evmAddress = u8aToHex(addressToEvm(fakeAddress)); // todo: move this
|
|
57
96
|
|
|
58
97
|
// mock receiving account from sender
|
|
59
|
-
const
|
|
98
|
+
const sender = _isChainEvmCompatible(originChainInfo) ? evmAddress : substrateAddress;
|
|
99
|
+
const recipient = _isChainEvmCompatible(destChainInfo) ? evmAddress : substrateAddress;
|
|
60
100
|
const mockTx = await createXcmExtrinsic({
|
|
61
101
|
chainInfoMap,
|
|
62
102
|
destinationTokenInfo,
|
|
63
103
|
originTokenInfo,
|
|
64
|
-
|
|
104
|
+
sender,
|
|
105
|
+
recipient,
|
|
65
106
|
sendingValue: '1000000000000000000',
|
|
66
107
|
substrateApi
|
|
67
108
|
});
|
|
68
|
-
const paymentInfo = await mockTx.paymentInfo(
|
|
109
|
+
const paymentInfo = await mockTx.paymentInfo(fakeAddress);
|
|
69
110
|
return new BigN((paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0');
|
|
70
111
|
} catch (e) {
|
|
71
112
|
console.error('error mocking xcm tx fee', e);
|
|
@@ -72,15 +72,11 @@ export class EvmApi {
|
|
|
72
72
|
createIntervalCheckApi() {
|
|
73
73
|
this.clearIntervalCheckApi();
|
|
74
74
|
return setInterval(() => {
|
|
75
|
-
|
|
76
|
-
this.api.eth.net.isListening().then(() => {
|
|
77
|
-
this.onConnect();
|
|
78
|
-
}).catch(() => {
|
|
79
|
-
this.onDisconnect();
|
|
80
|
-
});
|
|
81
|
-
} else {
|
|
75
|
+
this.api.eth.getChainId().then(() => {
|
|
82
76
|
this.onConnect();
|
|
83
|
-
}
|
|
77
|
+
}).catch(() => {
|
|
78
|
+
this.onDisconnect();
|
|
79
|
+
});
|
|
84
80
|
}, 10000);
|
|
85
81
|
}
|
|
86
82
|
clearIntervalCheckApi() {
|
|
@@ -93,21 +89,16 @@ export class EvmApi {
|
|
|
93
89
|
this.updateConnectionStatus(_ChainConnectionStatus.CONNECTING);
|
|
94
90
|
|
|
95
91
|
// Check if api is ready
|
|
96
|
-
|
|
97
|
-
this.api.eth.net.isListening().then(() => {
|
|
98
|
-
this.isApiReadyOnce = true;
|
|
99
|
-
this.onConnect();
|
|
100
|
-
}).catch(error => {
|
|
101
|
-
this.isApiReadyOnce = false;
|
|
102
|
-
this.isApiReady = false;
|
|
103
|
-
this.isReadyHandler.reject(error);
|
|
104
|
-
this.updateConnectionStatus(_ChainConnectionStatus.DISCONNECTED);
|
|
105
|
-
console.warn(`Can not connect to ${this.chainSlug} (EVM) at ${this.apiUrl}`);
|
|
106
|
-
});
|
|
107
|
-
} else {
|
|
92
|
+
this.api.eth.getChainId().then(() => {
|
|
108
93
|
this.isApiReadyOnce = true;
|
|
109
94
|
this.onConnect();
|
|
110
|
-
}
|
|
95
|
+
}).catch(error => {
|
|
96
|
+
this.isApiReadyOnce = false;
|
|
97
|
+
this.isApiReady = false;
|
|
98
|
+
this.isReadyHandler.reject(error);
|
|
99
|
+
this.updateConnectionStatus(_ChainConnectionStatus.DISCONNECTED);
|
|
100
|
+
console.warn(`Can not connect to ${this.chainSlug} (EVM) at ${this.apiUrl}`);
|
|
101
|
+
});
|
|
111
102
|
|
|
112
103
|
// Interval to check connecting status
|
|
113
104
|
this.intervalCheckApi = this.createIntervalCheckApi();
|
|
@@ -19,7 +19,9 @@ export declare class SubstrateChainHandler extends AbstractChainHandler {
|
|
|
19
19
|
private getPsp34TokenInfo;
|
|
20
20
|
private getGrc20TokenInfo;
|
|
21
21
|
private getVftTokenInfo;
|
|
22
|
+
private getLocalTokenInfo;
|
|
22
23
|
getSubstrateContractTokenInfo(contractAddress: string, tokenType: _AssetType, originChain: string, contractCaller?: string): Promise<_SmartContractTokenInfo>;
|
|
24
|
+
getSubstrateAssetIdTokenInfo(assetId: string, originChain: string): Promise<_SmartContractTokenInfo>;
|
|
23
25
|
setSubstrateApi(chainSlug: string, substrateApi: _SubstrateApi): void;
|
|
24
26
|
destroySubstrateApi(chainSlug: string): void;
|
|
25
27
|
initApi(chainSlug: string, apiUrl: string, { externalApiPromise, onUpdateStatus, providerName }?: Omit<_ApiOptions, 'metadata'>): Promise<_SubstrateApi>;
|
|
@@ -179,6 +179,15 @@ export class SubstrateChainHandler extends AbstractChainHandler {
|
|
|
179
179
|
}
|
|
180
180
|
return [nameRes, decimals, symbolRes, contractError];
|
|
181
181
|
}
|
|
182
|
+
async getLocalTokenInfo(apiPromise, assetId) {
|
|
183
|
+
const _metadata = await apiPromise.query.assets.metadata(assetId);
|
|
184
|
+
const metadata = _metadata.toPrimitive();
|
|
185
|
+
let idError = false;
|
|
186
|
+
if (!metadata.name || !metadata.symbol) {
|
|
187
|
+
idError = true;
|
|
188
|
+
}
|
|
189
|
+
return [metadata.name, metadata.decimals, metadata.symbol, idError];
|
|
190
|
+
}
|
|
182
191
|
async getSubstrateContractTokenInfo(contractAddress, tokenType, originChain, contractCaller) {
|
|
183
192
|
// todo: improve this funtion later
|
|
184
193
|
|
|
@@ -218,6 +227,26 @@ export class SubstrateChainHandler extends AbstractChainHandler {
|
|
|
218
227
|
};
|
|
219
228
|
}
|
|
220
229
|
}
|
|
230
|
+
async getSubstrateAssetIdTokenInfo(assetId, originChain) {
|
|
231
|
+
const apiPromise = this.getSubstrateApiByChain(originChain).api;
|
|
232
|
+
try {
|
|
233
|
+
const [name, decimals, symbol, contractError] = await this.getLocalTokenInfo(apiPromise, assetId);
|
|
234
|
+
return {
|
|
235
|
+
name,
|
|
236
|
+
decimals,
|
|
237
|
+
symbol,
|
|
238
|
+
contractError
|
|
239
|
+
};
|
|
240
|
+
} catch (e) {
|
|
241
|
+
this.logger.error(e);
|
|
242
|
+
return {
|
|
243
|
+
name: '',
|
|
244
|
+
decimals: -1,
|
|
245
|
+
symbol: '',
|
|
246
|
+
contractError: true
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
221
250
|
setSubstrateApi(chainSlug, substrateApi) {
|
|
222
251
|
this.substrateApiMap[chainSlug] = substrateApi;
|
|
223
252
|
}
|
|
@@ -63,6 +63,7 @@ export declare class ChainService {
|
|
|
63
63
|
getAssetRegistry(): Record<string, _ChainAsset>;
|
|
64
64
|
getMultiChainAssetMap(): Record<string, _MultiChainAsset>;
|
|
65
65
|
getSmartContractTokens(): Record<string, _ChainAsset>;
|
|
66
|
+
getAssetHubToken(): Record<string, _ChainAsset>;
|
|
66
67
|
getChainInfoMap(): Record<string, _ChainInfo>;
|
|
67
68
|
getEvmChainInfoMap(): Record<string, _ChainInfo>;
|
|
68
69
|
getSubstrateChainInfoMap(): Record<string, _ChainInfo>;
|
|
@@ -131,6 +132,7 @@ export declare class ChainService {
|
|
|
131
132
|
private getChainSpecByProvider;
|
|
132
133
|
private validateProvider;
|
|
133
134
|
private getSmartContractTokenInfo;
|
|
135
|
+
private getAssetIdTokenInfo;
|
|
134
136
|
validateCustomToken(data: _ValidateCustomAssetRequest): Promise<_ValidateCustomAssetResponse>;
|
|
135
137
|
private generateSlugForSmartContractAsset;
|
|
136
138
|
private generateSlugForNativeToken;
|
|
@@ -10,7 +10,7 @@ import { SubstrateChainHandler } from '@subwallet/extension-base/services/chain-
|
|
|
10
10
|
import { TonChainHandler } from '@subwallet/extension-base/services/chain-service/handler/TonChainHandler';
|
|
11
11
|
import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
|
|
12
12
|
import { _ChainConnectionStatus, _CUSTOM_PREFIX, _NFT_CONTRACT_STANDARDS, _SMART_CONTRACT_STANDARDS } from '@subwallet/extension-base/services/chain-service/types';
|
|
13
|
-
import { _isAssetAutoEnable, _isAssetCanPayTxFee, _isAssetFungibleToken, _isChainEnabled, _isCustomAsset, _isCustomChain, _isCustomProvider, _isEqualContractAddress, _isEqualSmartContractAsset, _isMantaZkAsset, _isPureEvmChain, _isPureSubstrateChain, _parseAssetRefKey, fetchPatchData, randomizeProvider, updateLatestChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
13
|
+
import { _isAssetAutoEnable, _isAssetCanPayTxFee, _isAssetFungibleToken, _isChainEnabled, _isCustomAsset, _isCustomChain, _isCustomProvider, _isEqualContractAddress, _isEqualSmartContractAsset, _isLocalToken, _isMantaZkAsset, _isPureEvmChain, _isPureSubstrateChain, _parseAssetRefKey, fetchPatchData, randomizeProvider, updateLatestChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
14
14
|
import AssetSettingStore from '@subwallet/extension-base/stores/AssetSetting';
|
|
15
15
|
import { addLazy, calculateMetadataHash, fetchStaticData, filterAssetsByChainAndType, getShortMetadata, MODULE_SUPPORT } from '@subwallet/extension-base/utils';
|
|
16
16
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
@@ -186,6 +186,15 @@ export class ChainService {
|
|
|
186
186
|
});
|
|
187
187
|
return filteredAssetRegistry;
|
|
188
188
|
}
|
|
189
|
+
getAssetHubToken() {
|
|
190
|
+
const assetHubToken = {};
|
|
191
|
+
Object.values(this.getAssetRegistry()).forEach(asset => {
|
|
192
|
+
if (['statemint', 'statemine'].includes(asset.originChain)) {
|
|
193
|
+
assetHubToken[asset.slug] = asset;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
return assetHubToken;
|
|
197
|
+
}
|
|
189
198
|
getChainInfoMap() {
|
|
190
199
|
return this.dataMap.chainInfoMap;
|
|
191
200
|
}
|
|
@@ -435,7 +444,7 @@ export class ChainService {
|
|
|
435
444
|
upsertCustomToken(token) {
|
|
436
445
|
if (token.slug.length === 0) {
|
|
437
446
|
// new token
|
|
438
|
-
if (token.assetType === _AssetType.NATIVE) {
|
|
447
|
+
if (token.assetType === _AssetType.NATIVE || token.assetType === _AssetType.LOCAL) {
|
|
439
448
|
const defaultSlug = this.generateSlugForNativeToken(token.originChain, token.assetType, token.symbol);
|
|
440
449
|
token.slug = `${_CUSTOM_PREFIX}${defaultSlug}`;
|
|
441
450
|
} else {
|
|
@@ -444,7 +453,7 @@ export class ChainService {
|
|
|
444
453
|
token.slug = `${_CUSTOM_PREFIX}${defaultSlug}`;
|
|
445
454
|
}
|
|
446
455
|
}
|
|
447
|
-
if (token.originChain && _isAssetFungibleToken(token)) {
|
|
456
|
+
if (token.originChain && (_isAssetFungibleToken(token) || _isLocalToken(token))) {
|
|
448
457
|
var _this$getChainInfoByK;
|
|
449
458
|
token.hasValue = !((_this$getChainInfoByK = this.getChainInfoByKey(token.originChain)) !== null && _this$getChainInfoByK !== void 0 && _this$getChainInfoByK.isTestnet);
|
|
450
459
|
}
|
|
@@ -1510,13 +1519,35 @@ export class ChainService {
|
|
|
1510
1519
|
contractError: false
|
|
1511
1520
|
};
|
|
1512
1521
|
}
|
|
1522
|
+
async getAssetIdTokenInfo(assetId, tokenType, chain) {
|
|
1523
|
+
if ([_AssetType.LOCAL].includes(tokenType) && assetId) {
|
|
1524
|
+
return await this.substrateChainHandler.getSubstrateAssetIdTokenInfo(assetId, chain);
|
|
1525
|
+
}
|
|
1526
|
+
return {
|
|
1527
|
+
decimals: -1,
|
|
1528
|
+
name: '',
|
|
1529
|
+
symbol: '',
|
|
1530
|
+
contractError: false
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1513
1533
|
async validateCustomToken(data) {
|
|
1514
1534
|
const assetRegistry = this.getSmartContractTokens();
|
|
1535
|
+
const asset = this.getAssetHubToken();
|
|
1515
1536
|
let existedToken;
|
|
1516
1537
|
for (const token of Object.values(assetRegistry)) {
|
|
1517
1538
|
var _token$metadata2;
|
|
1518
1539
|
const contractAddress = token === null || token === void 0 ? void 0 : (_token$metadata2 = token.metadata) === null || _token$metadata2 === void 0 ? void 0 : _token$metadata2.contractAddress;
|
|
1519
|
-
if (
|
|
1540
|
+
if (data.contractAddress) {
|
|
1541
|
+
if (_isEqualContractAddress(contractAddress, data.contractAddress) && token.assetType === data.type && token.originChain === data.originChain) {
|
|
1542
|
+
existedToken = token;
|
|
1543
|
+
break;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
for (const token of Object.values(asset)) {
|
|
1548
|
+
var _token$metadata3;
|
|
1549
|
+
const assetId = token === null || token === void 0 ? void 0 : (_token$metadata3 = token.metadata) === null || _token$metadata3 === void 0 ? void 0 : _token$metadata3.assetId;
|
|
1550
|
+
if (assetId === data.assetId && token.assetType === data.type && token.originChain === data.originChain) {
|
|
1520
1551
|
existedToken = token;
|
|
1521
1552
|
break;
|
|
1522
1553
|
}
|
|
@@ -1532,18 +1563,18 @@ export class ChainService {
|
|
|
1532
1563
|
contractError: false
|
|
1533
1564
|
};
|
|
1534
1565
|
}
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
}
|
|
1566
|
+
let info;
|
|
1567
|
+
if (data.contractAddress) {
|
|
1568
|
+
info = await this.getSmartContractTokenInfo(data.contractAddress, data.type, data.originChain, data.contractCaller);
|
|
1569
|
+
} else {
|
|
1570
|
+
info = await this.getAssetIdTokenInfo(data.assetId, data.type, data.originChain);
|
|
1571
|
+
}
|
|
1541
1572
|
return {
|
|
1542
|
-
name,
|
|
1543
|
-
decimals,
|
|
1544
|
-
symbol,
|
|
1573
|
+
name: info.name,
|
|
1574
|
+
decimals: info.decimals,
|
|
1575
|
+
symbol: info.symbol,
|
|
1545
1576
|
isExist: !!existedToken,
|
|
1546
|
-
contractError
|
|
1577
|
+
contractError: info.contractError
|
|
1547
1578
|
};
|
|
1548
1579
|
}
|
|
1549
1580
|
generateSlugForSmartContractAsset(originChain, assetType, symbol, contractAddress) {
|
|
@@ -160,10 +160,11 @@ export interface EnableMultiChainParams {
|
|
|
160
160
|
enableTokens?: boolean;
|
|
161
161
|
}
|
|
162
162
|
export interface _ValidateCustomAssetRequest {
|
|
163
|
-
contractAddress
|
|
163
|
+
contractAddress?: string;
|
|
164
164
|
originChain: string;
|
|
165
165
|
type: _AssetType;
|
|
166
166
|
contractCaller?: string;
|
|
167
|
+
assetId?: string;
|
|
167
168
|
}
|
|
168
169
|
export interface _SmartContractTokenInfo {
|
|
169
170
|
name: string;
|
|
@@ -53,6 +53,8 @@ export declare function _isChainSupportEvmNft(chainInfo: _ChainInfo): boolean;
|
|
|
53
53
|
export declare function _isChainSupportWasmNft(chainInfo: _ChainInfo): boolean;
|
|
54
54
|
export declare function _isChainSupportEvmERC20(chainInfo: _ChainInfo): boolean;
|
|
55
55
|
export declare function _isChainSupportWasmPSP22(chainInfo: _ChainInfo): boolean;
|
|
56
|
+
export declare function _isAssetHubChain(chainInfo: _ChainInfo): boolean;
|
|
57
|
+
export declare function _isAssetHubToken(token: _ChainAsset): boolean;
|
|
56
58
|
export declare function _isChainSupportGRC20(chainInfo: _ChainInfo): boolean;
|
|
57
59
|
export declare function _isChainSupportVFT(chainInfo: _ChainInfo): boolean;
|
|
58
60
|
export declare const _isSupportOrdinal: (chain: string) => boolean;
|
|
@@ -88,6 +90,7 @@ export declare function _getChainName(chainInfo?: _ChainInfo): string;
|
|
|
88
90
|
export declare function _getAssetDecimals(assetInfo?: _ChainAsset): number;
|
|
89
91
|
export declare function _getBlockExplorerFromChain(chainInfo: _ChainInfo): string | undefined;
|
|
90
92
|
export declare function _parseMetadataForSmartContractAsset(contractAddress: string): Record<string, string>;
|
|
93
|
+
export declare function _parseMetadataForAssetId(assetId: string): Record<string, string>;
|
|
91
94
|
export declare function _isChainTestNet(chainInfo: _ChainInfo): boolean;
|
|
92
95
|
export declare function _isAssetFungibleToken(chainAsset: _ChainAsset): boolean;
|
|
93
96
|
export declare const _isAssetAutoEnable: (chainAsset: _ChainAsset) => boolean;
|
|
@@ -194,6 +194,12 @@ export function _isChainSupportWasmPSP22(chainInfo) {
|
|
|
194
194
|
var _chainInfo$substrateI10, _chainInfo$substrateI11;
|
|
195
195
|
return ((_chainInfo$substrateI10 = chainInfo.substrateInfo) === null || _chainInfo$substrateI10 === void 0 ? void 0 : (_chainInfo$substrateI11 = _chainInfo$substrateI10.supportSmartContract) === null || _chainInfo$substrateI11 === void 0 ? void 0 : _chainInfo$substrateI11.includes(_AssetType.PSP22)) || false;
|
|
196
196
|
}
|
|
197
|
+
export function _isAssetHubChain(chainInfo) {
|
|
198
|
+
return ['statemint', 'statemine'].includes(chainInfo.slug);
|
|
199
|
+
}
|
|
200
|
+
export function _isAssetHubToken(token) {
|
|
201
|
+
return ['statemint', 'statemine'].includes(token.originChain);
|
|
202
|
+
}
|
|
197
203
|
export function _isChainSupportGRC20(chainInfo) {
|
|
198
204
|
var _chainInfo$substrateI12, _chainInfo$substrateI13;
|
|
199
205
|
return ((_chainInfo$substrateI12 = chainInfo.substrateInfo) === null || _chainInfo$substrateI12 === void 0 ? void 0 : (_chainInfo$substrateI13 = _chainInfo$substrateI12.supportSmartContract) === null || _chainInfo$substrateI13 === void 0 ? void 0 : _chainInfo$substrateI13.includes(_AssetType.GRC20)) || false;
|
|
@@ -240,6 +246,9 @@ export function _getTokenTypesSupportedByChain(chainInfo) {
|
|
|
240
246
|
}
|
|
241
247
|
});
|
|
242
248
|
}
|
|
249
|
+
if (['statemint', 'statemine'].includes(chainInfo.slug)) {
|
|
250
|
+
result.push(_AssetType.LOCAL);
|
|
251
|
+
}
|
|
243
252
|
return result;
|
|
244
253
|
}
|
|
245
254
|
export function _getChainNativeTokenBasicInfo(chainInfo) {
|
|
@@ -393,6 +402,11 @@ export function _parseMetadataForSmartContractAsset(contractAddress) {
|
|
|
393
402
|
contractAddress
|
|
394
403
|
};
|
|
395
404
|
}
|
|
405
|
+
export function _parseMetadataForAssetId(assetId) {
|
|
406
|
+
return {
|
|
407
|
+
assetId
|
|
408
|
+
};
|
|
409
|
+
}
|
|
396
410
|
export function _isChainTestNet(chainInfo) {
|
|
397
411
|
return chainInfo.isTestnet || false;
|
|
398
412
|
}
|
|
@@ -45,6 +45,8 @@ export default abstract class BasePoolHandler {
|
|
|
45
45
|
protected abstract getDescription(amount?: string): string;
|
|
46
46
|
protected get maintainBalance(): string;
|
|
47
47
|
get metadataInfo(): Omit<BaseYieldPoolMetadata, 'description'>;
|
|
48
|
+
createWithdrawNotifications(unstakingInfos: UnstakingInfo[], tokenInfo: _ChainAsset, address: string): Promise<void>;
|
|
49
|
+
createClaimNotification(claimItemInfo: EarningRewardItem, tokenInfo: _ChainAsset): Promise<void>;
|
|
48
50
|
/** Can mint when haven't enough native token (use input token for fee) */
|
|
49
51
|
get isPoolSupportAlternativeFee(): boolean;
|
|
50
52
|
getPoolInfo(): Promise<YieldPoolInfo | undefined>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { ChainType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
5
|
import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
|
|
6
6
|
import { DEFAULT_YIELD_FIRST_STEP } from '@subwallet/extension-base/services/earning-service/constants';
|
|
7
|
+
import { createClaimNotification, createWithdrawNotifications } from '@subwallet/extension-base/services/inapp-notification-service/utils';
|
|
7
8
|
import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
8
9
|
import { BN, BN_TEN } from '@polkadot/util';
|
|
9
10
|
|
|
@@ -77,7 +78,8 @@ export default class BasePoolHandler {
|
|
|
77
78
|
const decimals = this.nativeToken.decimals || 0;
|
|
78
79
|
const defaultMaintainBalance = new BN(1).mul(BN_TEN.pow(new BN(decimals)));
|
|
79
80
|
const ed = new BN(this.nativeToken.minAmount || '0');
|
|
80
|
-
const
|
|
81
|
+
const calculateMaintainBalance = new BN(15).mul(ed).div(BN_TEN);
|
|
82
|
+
const maintainBalance = ed.gte(defaultMaintainBalance) ? calculateMaintainBalance : defaultMaintainBalance;
|
|
81
83
|
return maintainBalance.toString();
|
|
82
84
|
}
|
|
83
85
|
get metadataInfo() {
|
|
@@ -92,6 +94,14 @@ export default class BasePoolHandler {
|
|
|
92
94
|
availableMethod: this.availableMethod
|
|
93
95
|
};
|
|
94
96
|
}
|
|
97
|
+
async createWithdrawNotifications(unstakingInfos, tokenInfo, address) {
|
|
98
|
+
const notifications = createWithdrawNotifications(unstakingInfos, tokenInfo, address, this.baseInfo.slug, this.type);
|
|
99
|
+
await this.state.inappNotificationService.validateAndWriteNotificationsToDB(notifications, address);
|
|
100
|
+
}
|
|
101
|
+
async createClaimNotification(claimItemInfo, tokenInfo) {
|
|
102
|
+
const notification = createClaimNotification(claimItemInfo, tokenInfo);
|
|
103
|
+
await this.state.inappNotificationService.validateAndWriteNotificationsToDB([notification], claimItemInfo.address);
|
|
104
|
+
}
|
|
95
105
|
|
|
96
106
|
/** Can mint when haven't enough native token (use input token for fee) */
|
|
97
107
|
get isPoolSupportAlternativeFee() {
|