diff --git a/packages/background/src/keyring-cosmos/service.ts b/packages/background/src/keyring-cosmos/service.ts index 96a713ea74..3afd00a7aa 100644 --- a/packages/background/src/keyring-cosmos/service.ts +++ b/packages/background/src/keyring-cosmos/service.ts @@ -220,6 +220,9 @@ export class KeyRingCosmosService { signOptions: KeplrSignOptions ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); const keyInfo = this.keyRingService.getKeyInfo(vaultId); @@ -346,6 +349,9 @@ export class KeyRingCosmosService { } const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const vaultId = this.keyRingService.selectedVaultId; @@ -443,6 +449,9 @@ export class KeyRingCosmosService { } const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const vaultId = this.keyRingService.selectedVaultId; @@ -561,6 +570,9 @@ export class KeyRingCosmosService { } ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); const keyInfo = this.keyRingService.getKeyInfo(vaultId); @@ -654,6 +666,9 @@ export class KeyRingCosmosService { signOptions: KeplrSignOptions ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); const keyInfo = this.keyRingService.getKeyInfo(vaultId); @@ -769,6 +784,9 @@ export class KeyRingCosmosService { > ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); const keyInfo = this.keyRingService.getKeyInfo(vaultId); @@ -972,6 +990,9 @@ export class KeyRingCosmosService { signOptions: KeplrSignOptions ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); if (!isEthermintLike) { @@ -1129,6 +1150,9 @@ export class KeyRingCosmosService { { // Do this on other code block to avoid variable conflict. const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } Bech32Address.validate( contractAddress, diff --git a/packages/background/src/keyring-ethereum/service.ts b/packages/background/src/keyring-ethereum/service.ts index 2aa3f2f2f8..a8c060dd9b 100644 --- a/packages/background/src/keyring-ethereum/service.ts +++ b/packages/background/src/keyring-ethereum/service.ts @@ -58,6 +58,9 @@ export class KeyRingEthereumService { signType: EthSignType ): Promise { const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + throw new Error("Can't sign for hidden chain"); + } const isEthermintLike = KeyRingService.isEthermintLike(chainInfo); const evmInfo = KeyRingEthereumService.evmInfo(chainInfo); diff --git a/packages/background/src/token-scan/service.ts b/packages/background/src/token-scan/service.ts index 533761a8ba..9953a2d2c4 100644 --- a/packages/background/src/token-scan/service.ts +++ b/packages/background/src/token-scan/service.ts @@ -99,6 +99,11 @@ export class TokenScanService { return; } + const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + return; + } + const vaultIds = this.keyRingService .getKeyInfos() .map((keyInfo) => keyInfo.id) @@ -126,6 +131,11 @@ export class TokenScanService { return; } + const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + return; + } + const tokenScan = await this.calculateTokenScan(vaultId, chainId); if (tokenScan) { @@ -221,6 +231,9 @@ export class TokenScanService { } const chainInfo = this.chainsService.getChainInfoOrThrow(chainId); + if (chainInfo.hideInUI) { + return; + } if (this.chainsUIService.isEnabled(vaultId, chainId)) { return; diff --git a/packages/chain-validator/src/schema.ts b/packages/chain-validator/src/schema.ts index 1d98764ce5..acd3d0469c 100644 --- a/packages/chain-validator/src/schema.ts +++ b/packages/chain-validator/src/schema.ts @@ -245,6 +245,7 @@ export const ChainInfoSchema = Joi.object({ return value; }), chainSymbolImageUrl: Joi.string().uri(), + hideInUI: Joi.boolean(), }).custom((value: ChainInfo) => { if ( value.alternativeBIP44s?.find( diff --git a/packages/extension/src/pages/main/available.tsx b/packages/extension/src/pages/main/available.tsx index 308da2a01c..72d59353e7 100644 --- a/packages/extension/src/pages/main/available.tsx +++ b/packages/extension/src/pages/main/available.tsx @@ -93,7 +93,7 @@ export const AvailableTabView: FunctionComponent<{ : _allBalancesSearchFiltered; const lookingForChains = (() => { - return chainStore.chainInfos.filter((chainInfo) => { + return chainStore.chainInfosInListUI.filter((chainInfo) => { if (chainStore.isEnabledChain(chainInfo.chainId)) { return false; } diff --git a/packages/extension/src/pages/register/enable-chains/index.tsx b/packages/extension/src/pages/register/enable-chains/index.tsx index 9fa3cac8c9..f3104a2fce 100644 --- a/packages/extension/src/pages/register/enable-chains/index.tsx +++ b/packages/extension/src/pages/register/enable-chains/index.tsx @@ -337,6 +337,13 @@ export const EnableChainsScene: FunctionComponent<{ const queries = queriesStore.get(candidateAddress.chainId); const chainInfo = chainStore.getChain(candidateAddress.chainId); + // hideInUI인 chain은 UI 상에서 enable이 되지 않아야한다. + // 정말 만약의 수로 왜인지 그 체인에 유저가 자산등을 가지고 있을수도 있으니 + // 여기서도 막아야한다 + if (!chainStore.isInChainInfosInListUI(chainInfo.chainId)) { + continue; + } + // If the chain is already enabled, skip. if (chainStore.isEnabledChain(candidateAddress.chainId)) { continue; @@ -417,7 +424,7 @@ export const EnableChainsScene: FunctionComponent<{ // 그래서 이를 위한 변수로 따로 둔다. // 실제로는 chainInfos를 사용하면 된다. const preSortChainInfos = useMemo(() => { - let chainInfos = chainStore.chainInfos.slice(); + let chainInfos = chainStore.chainInfosInListUI.slice(); if (keyType === "ledger") { chainInfos = chainInfos.filter((chainInfo) => { @@ -470,7 +477,12 @@ export const EnableChainsScene: FunctionComponent<{ ); }); } - }, [chainStore.chainInfos, fallbackEthereumLedgerApp, keyType, search]); + }, [ + chainStore.chainInfosInListUI, + fallbackEthereumLedgerApp, + keyType, + search, + ]); const chainInfos = preSortChainInfos.sort((a, b) => { const aHasPriority = sortPriorityChainIdentifierMap.has( a.chainIdentifier diff --git a/packages/extension/src/pages/setting/token/add/index.tsx b/packages/extension/src/pages/setting/token/add/index.tsx index 4cc46c5769..19a47116af 100644 --- a/packages/extension/src/pages/setting/token/add/index.tsx +++ b/packages/extension/src/pages/setting/token/add/index.tsx @@ -65,14 +65,14 @@ export const SettingTokenAddPage: FunctionComponent = observer(() => { }); const supportedChainInfos = useMemo(() => { - return chainStore.chainInfos.filter((chainInfo) => { + return chainStore.chainInfosInListUI.filter((chainInfo) => { return ( chainInfo.features?.includes("cosmwasm") || chainInfo.features?.includes("secretwasm") || chainInfo.evm !== undefined ); }); - }, [chainStore.chainInfos]); + }, [chainStore.chainInfosInListUI]); const [chainId, setChainId] = useState(() => { if (paramChainId) { diff --git a/packages/extension/src/pages/setting/token/manage/index.tsx b/packages/extension/src/pages/setting/token/manage/index.tsx index c6d6865122..b8fc29f5bf 100644 --- a/packages/extension/src/pages/setting/token/manage/index.tsx +++ b/packages/extension/src/pages/setting/token/manage/index.tsx @@ -44,14 +44,14 @@ export const SettingTokenListPage: FunctionComponent = observer(() => { const navigate = useNavigate(); const supportedChainInfos = useMemo(() => { - return chainStore.chainInfos.filter((chainInfo) => { + return chainStore.chainInfosInListUI.filter((chainInfo) => { return ( chainInfo.features?.includes("cosmwasm") || chainInfo.features?.includes("secretwasm") || chainInfo.evm !== undefined ); }); - }, [chainStore.chainInfos]); + }, [chainStore.chainInfosInListUI]); const [chainId, setChainId] = useState(() => { if (supportedChainInfos.length > 0) { diff --git a/packages/extension/src/stores/chain/index.tsx b/packages/extension/src/stores/chain/index.tsx index 0284689973..19ec8f806e 100644 --- a/packages/extension/src/stores/chain/index.tsx +++ b/packages/extension/src/stores/chain/index.tsx @@ -159,16 +159,45 @@ export class ChainStore extends BaseChainStore { @computed get chainInfosInUI() { return this.chainInfos.filter((chainInfo) => { + if (chainInfo.hideInUI) { + return false; + } const chainIdentifier = ChainIdHelper.parse(chainInfo.chainId).identifier; return this.enabledChainIdentifiesMap.get(chainIdentifier); }); } + // chain info들을 list로 보여줄때 hideInUI인 얘들은 빼고 보여줘야한다 + // property 이름이 얘매해서 일단 이렇게 지었다. + @computed + get chainInfosInListUI() { + return this.chainInfos.filter((chainInfo) => { + return !chainInfo.hideInUI; + }); + } + isEnabledChain(chainId: string): boolean { const chainIdentifier = ChainIdHelper.parse(chainId).identifier; return this.enabledChainIdentifiesMap.get(chainIdentifier) === true; } + @computed + protected get chainInfosInListUIMap(): Map { + const map = new Map(); + for (const chainInfo of this.chainInfosInListUI) { + map.set(chainInfo.chainIdentifier, true); + } + return map; + } + + isInChainInfosInListUI(chainId: string): boolean { + return ( + this.chainInfosInListUIMap.get( + ChainIdHelper.parse(chainId).identifier + ) === true + ); + } + @flow *toggleChainInfoInUI(...chainIds: string[]) { if (!this.keyRingStore.selectedKeyInfo) { diff --git a/packages/extension/src/stores/skip/assets-from-source.ts b/packages/extension/src/stores/skip/assets-from-source.ts index 327bd4868b..51c4742b84 100644 --- a/packages/extension/src/stores/skip/assets-from-source.ts +++ b/packages/extension/src/stores/skip/assets-from-source.ts @@ -1,5 +1,4 @@ import { - ChainGetter, HasMapStore, ObservableQuery, QuerySharedContext, @@ -9,6 +8,7 @@ import { simpleFetch } from "@keplr-wallet/simple-fetch"; import { computed, makeObservable } from "mobx"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; import Joi from "joi"; +import { ChainStore } from "../chain"; const Schema = Joi.object({ dest_assets: Joi.object() @@ -31,7 +31,7 @@ const Schema = Joi.object({ export class ObservableQueryAssetsFromSourceInner extends ObservableQuery { constructor( sharedContext: QuerySharedContext, - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, skipURL: string, public readonly chainId: string, public readonly denom: string @@ -74,9 +74,14 @@ export class ObservableQueryAssetsFromSourceInner extends ObservableQuery { return ( - this.chainGetter.hasChain(asset.chain_id) && - this.chainGetter.hasChain(asset.origin_chain_id) + this.chainStore.hasChain(asset.chain_id) && + this.chainStore.hasChain(asset.origin_chain_id) ); }) .map((asset) => { @@ -154,14 +159,14 @@ export class ObservableQueryAssetsFromSourceInner extends ObservableQuery { constructor( protected readonly sharedContext: QuerySharedContext, - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, protected readonly skipURL: string ) { super((str) => { const parsed = JSON.parse(str); return new ObservableQueryAssetsFromSourceInner( this.sharedContext, - this.chainGetter, + this.chainStore, this.skipURL, parsed.chainId, parsed.denom diff --git a/packages/extension/src/stores/skip/assets.ts b/packages/extension/src/stores/skip/assets.ts index b5d1543c8f..ac445512b2 100644 --- a/packages/extension/src/stores/skip/assets.ts +++ b/packages/extension/src/stores/skip/assets.ts @@ -1,5 +1,4 @@ import { - ChainGetter, HasMapStore, ObservableQuery, QuerySharedContext, @@ -7,6 +6,7 @@ import { import { AssetsResponse } from "./types"; import { computed, makeObservable } from "mobx"; import Joi from "joi"; +import { ChainStore } from "../chain"; const Schema = Joi.object({ chain_to_assets_map: Joi.object().pattern( @@ -27,7 +27,7 @@ const Schema = Joi.object({ export class ObservableQueryAssetsInner extends ObservableQuery { constructor( sharedContext: QuerySharedContext, - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, skipURL: string, public readonly chainId: string ) { @@ -55,11 +55,14 @@ export class ObservableQueryAssetsInner extends ObservableQuery return []; } - if (!this.chainGetter.hasChain(this.chainId)) { + if (!this.chainStore.hasChain(this.chainId)) { return []; } - const chainInfo = this.chainGetter.getChain(this.chainId); + const chainInfo = this.chainStore.getChain(this.chainId); + if (!this.chainStore.isInChainInfosInListUI(chainInfo.chainId)) { + return []; + } const assetsInResponse = this.response.data.chain_to_assets_map[chainInfo.chainId]; @@ -73,8 +76,8 @@ export class ObservableQueryAssetsInner extends ObservableQuery for (const asset of assetsInResponse.assets) { if ( - this.chainGetter.hasChain(asset.chain_id) && - this.chainGetter.hasChain(asset.origin_chain_id) + this.chainStore.hasChain(asset.chain_id) && + this.chainStore.hasChain(asset.origin_chain_id) ) { // IBC asset일 경우 그냥 넣는다. if (asset.denom.startsWith("ibc/")) { @@ -126,13 +129,13 @@ export class ObservableQueryAssetsInner extends ObservableQuery export class ObservableQueryAssets extends HasMapStore { constructor( protected readonly sharedContext: QuerySharedContext, - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, protected readonly skipURL: string ) { super((chainId) => { return new ObservableQueryAssetsInner( this.sharedContext, - this.chainGetter, + this.chainStore, this.skipURL, chainId ); diff --git a/packages/extension/src/stores/skip/chains.ts b/packages/extension/src/stores/skip/chains.ts index 7ce6b859c3..7b3a902876 100644 --- a/packages/extension/src/stores/skip/chains.ts +++ b/packages/extension/src/stores/skip/chains.ts @@ -1,5 +1,4 @@ import { - ChainGetter, IChainInfoImpl, ObservableQuery, QuerySharedContext, @@ -9,6 +8,7 @@ import { computed, makeObservable } from "mobx"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; import { computedFn } from "mobx-utils"; import Joi from "joi"; +import { ChainStore } from "../chain"; const Schema = Joi.object({ chains: Joi.array().items( @@ -23,7 +23,7 @@ const Schema = Joi.object({ export class ObservableQueryChains extends ObservableQuery { constructor( sharedContext: QuerySharedContext, - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, protected readonly skipURL: string ) { super(sharedContext, skipURL, "/v1/info/chains"); @@ -60,11 +60,14 @@ export class ObservableQueryChains extends ObservableQuery { return this.response.data.chains .filter((chain) => { - return this.chainGetter.hasChain(chain.chain_id); + return this.chainStore.hasChain(chain.chain_id); + }) + .filter((chain) => { + return this.chainStore.isInChainInfosInListUI(chain.chain_id); }) .map((chain) => { return { - chainInfo: this.chainGetter.getChain(chain.chain_id), + chainInfo: this.chainStore.getChain(chain.chain_id), pfmEnabled: chain.pfm_enabled, supportsMemo: chain.supports_memo ?? false, }; diff --git a/packages/extension/src/stores/skip/ibc-pfm-transfer.ts b/packages/extension/src/stores/skip/ibc-pfm-transfer.ts index d75052222c..83965db979 100644 --- a/packages/extension/src/stores/skip/ibc-pfm-transfer.ts +++ b/packages/extension/src/stores/skip/ibc-pfm-transfer.ts @@ -1,12 +1,12 @@ -import { ChainGetter } from "@keplr-wallet/stores"; import { ObservableQueryAssetsFromSource } from "./assets-from-source"; import { ObservableQueryChains } from "./chains"; import { computedFn } from "mobx-utils"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; +import { ChainStore } from "../chain"; export class ObservableQueryIbcPfmTransfer { constructor( - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, protected readonly queryChains: ObservableQueryChains, protected readonly queryAssetsFromSource: ObservableQueryAssetsFromSource ) {} @@ -29,11 +29,11 @@ export class ObservableQueryIbcPfmTransfer { denom: string; }[] => { - if (!this.chainGetter.hasChain(chainId)) { + if (!this.chainStore.hasChain(chainId)) { return []; } - if (!this.chainGetter.getChain(chainId).hasFeature("ibc-transfer")) { + if (!this.chainStore.getChain(chainId).hasFeature("ibc-transfer")) { return []; } @@ -62,7 +62,7 @@ export class ObservableQueryIbcPfmTransfer { }[] = []; for (const assetChainId of Object.keys(assetsFromSource)) { - if (this.chainGetter.hasChain(assetChainId)) { + if (this.chainStore.hasChain(assetChainId)) { const assets = assetsFromSource[assetChainId]!.assets; // TODO: 미래에는 assets가 두개 이상이 될수도 있다고 한다. // 근데 지금은 한개로만 고정되어 있다고 한다... @@ -71,9 +71,13 @@ export class ObservableQueryIbcPfmTransfer { const asset = assets[0]; if ( asset.chainId === assetChainId && - this.chainGetter.hasChain(asset.chainId) && - this.chainGetter.hasChain(asset.originChainId) + this.chainStore.hasChain(asset.chainId) && + this.chainStore.hasChain(asset.originChainId) ) { + if (!this.chainStore.isInChainInfosInListUI(asset.chainId)) { + continue; + } + const channels: { portId: string; channelId: string; @@ -81,10 +85,10 @@ export class ObservableQueryIbcPfmTransfer { counterpartyChainId: string; }[] = []; - const currency = this.chainGetter + const currency = this.chainStore .getChain(chainId) .findCurrency(denom); - const destinationCurrency = this.chainGetter + const destinationCurrency = this.chainStore .getChain(asset.chainId) .findCurrency(asset.denom); @@ -98,7 +102,7 @@ export class ObservableQueryIbcPfmTransfer { if ( !currency.originChainId || !currency.originCurrency || - !this.chainGetter.hasChain(currency.originChainId) + !this.chainStore.hasChain(currency.originChainId) ) { continue; } @@ -119,7 +123,7 @@ export class ObservableQueryIbcPfmTransfer { !path.counterpartyPortId || !path.counterpartyChannelId || !path.clientChainId || - !this.chainGetter.hasChain(path.clientChainId) + !this.chainStore.hasChain(path.clientChainId) ); }) ) { @@ -150,9 +154,7 @@ export class ObservableQueryIbcPfmTransfer { if ( !destinationCurrency.originChainId || !destinationCurrency.originCurrency || - !this.chainGetter.hasChain( - destinationCurrency.originChainId - ) + !this.chainStore.hasChain(destinationCurrency.originChainId) ) { continue; } @@ -174,7 +176,7 @@ export class ObservableQueryIbcPfmTransfer { !path.counterpartyPortId || !path.counterpartyChannelId || !path.clientChainId || - !this.chainGetter.hasChain(path.clientChainId) + !this.chainStore.hasChain(path.clientChainId) ); }) ) { @@ -202,7 +204,7 @@ export class ObservableQueryIbcPfmTransfer { // (If channel is only one, no need to check packet forwarding because it is direct transfer) if (channels.length > 1) { if ( - !this.chainGetter.getChain(chainId).hasFeature("ibc-go") || + !this.chainStore.getChain(chainId).hasFeature("ibc-go") || !this.queryChains.isSupportsMemo(chainId) ) { pfmPossibility = false; @@ -212,7 +214,7 @@ export class ObservableQueryIbcPfmTransfer { for (let i = 0; i < channels.length - 1; i++) { const channel = channels[i]; if ( - !this.chainGetter + !this.chainStore .getChain(channel.counterpartyChainId) .hasFeature("ibc-go") || !this.queryChains.isSupportsMemo( @@ -221,7 +223,7 @@ export class ObservableQueryIbcPfmTransfer { !this.queryChains.isPFMEnabled( channel.counterpartyChainId ) || - !this.chainGetter + !this.chainStore .getChain(channel.counterpartyChainId) .hasFeature("ibc-pfm") ) { @@ -260,11 +262,11 @@ export class ObservableQueryIbcPfmTransfer { }) .sort((a, b) => { // Sort by chain name. - return this.chainGetter + return this.chainStore .getChain(a.destinationChainId) .chainName.trim() .localeCompare( - this.chainGetter.getChain(b.destinationChainId).chainName.trim() + this.chainStore.getChain(b.destinationChainId).chainName.trim() ); }); } diff --git a/packages/extension/src/stores/skip/ibc-swap.ts b/packages/extension/src/stores/skip/ibc-swap.ts index 34c02a9d5c..9ee1bdc461 100644 --- a/packages/extension/src/stores/skip/ibc-swap.ts +++ b/packages/extension/src/stores/skip/ibc-swap.ts @@ -1,9 +1,4 @@ -import { - ChainGetter, - HasMapStore, - IChainInfoImpl, - IChainStore, -} from "@keplr-wallet/stores"; +import { HasMapStore, IChainInfoImpl } from "@keplr-wallet/stores"; import { AppCurrency, Currency } from "@keplr-wallet/types"; import { ObservableQueryAssets } from "./assets"; import { computed, makeObservable } from "mobx"; @@ -18,10 +13,11 @@ import { computedFn } from "mobx-utils"; import { ObservableQueryIbcPfmTransfer } from "./ibc-pfm-transfer"; import { ObservableQueryAssetsFromSource } from "./assets-from-source"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; +import { ChainStore } from "../chain"; export class ObservableQueryIBCSwapInner { constructor( - protected readonly chainGetter: ChainGetter, + protected readonly chainStore: ChainStore, protected readonly queryRoute: ObservableQueryRoute, protected readonly queryMsgsDirect: ObservableQueryMsgsDirect, public readonly amountInDenom: string, @@ -42,7 +38,7 @@ export class ObservableQueryIBCSwapInner { affiliateFeeReceiver: string ): ObservableQueryMsgsDirectInner { const inAmount = new CoinPretty( - this.chainGetter + this.chainStore .getChain(this.sourceAssetChainId) .forceFindCurrency(this.amountInDenom), this.amountInAmount @@ -63,7 +59,7 @@ export class ObservableQueryIBCSwapInner { getQueryRoute(): ObservableQueryRouteInner { const inAmount = new CoinPretty( - this.chainGetter + this.chainStore .getChain(this.sourceAssetChainId) .forceFindCurrency(this.amountInDenom), this.amountInAmount @@ -82,7 +78,7 @@ export class ObservableQueryIBCSwapInner { export class ObservableQueryIbcSwap extends HasMapStore { constructor( - protected readonly chainStore: IChainStore, + protected readonly chainStore: ChainStore, protected readonly queryAssets: ObservableQueryAssets, protected readonly queryAssetsFromSource: ObservableQueryAssetsFromSource, protected readonly queryChains: ObservableQueryChains, @@ -151,6 +147,9 @@ export class ObservableQueryIbcSwap extends HasMapStore { + return this.chainStore.isInChainInfosInListUI(chainId); + }); } ); } diff --git a/packages/extension/src/stores/skip/queries.ts b/packages/extension/src/stores/skip/queries.ts index 5d0eee8f32..d7b3b9cd64 100644 --- a/packages/extension/src/stores/skip/queries.ts +++ b/packages/extension/src/stores/skip/queries.ts @@ -1,4 +1,4 @@ -import { IChainStore, QuerySharedContext } from "@keplr-wallet/stores"; +import { QuerySharedContext } from "@keplr-wallet/stores"; import { DeepReadonly } from "utility-types"; import { ObservableQueryAssetsFromSource } from "./assets-from-source"; import { ObservableQueryRoute } from "./route"; @@ -8,6 +8,7 @@ import { ObservableQueryAssets } from "./assets"; import { ObservableQueryIbcSwap } from "./ibc-swap"; import { ObservableQueryMsgsDirect } from "./msgs-direct"; import { SwapVenue } from "../../config.ui"; +import { ChainStore } from "../chain"; export class SkipQueries { public readonly queryChains: DeepReadonly; @@ -20,41 +21,41 @@ export class SkipQueries { public readonly queryIBCPacketForwardingTransfer: DeepReadonly; public readonly queryIBCSwap: DeepReadonly; - constructor(sharedContext: QuerySharedContext, chainGetter: IChainStore) { + constructor(sharedContext: QuerySharedContext, chainStore: ChainStore) { this.queryChains = new ObservableQueryChains( sharedContext, - chainGetter, + chainStore, "https://api.skip.money" ); this.queryAssets = new ObservableQueryAssets( sharedContext, - chainGetter, + chainStore, "https://api.skip.money" ); this.queryAssetsFromSource = new ObservableQueryAssetsFromSource( sharedContext, - chainGetter, + chainStore, "https://api.skip.money" ); this.queryRoute = new ObservableQueryRoute( sharedContext, - chainGetter, + chainStore, "https://api.skip.money" ); this.queryMsgsDirect = new ObservableQueryMsgsDirect( sharedContext, - chainGetter, + chainStore, "https://api.skip.money" ); this.queryIBCPacketForwardingTransfer = new ObservableQueryIbcPfmTransfer( - chainGetter, + chainStore, this.queryChains, this.queryAssetsFromSource ); this.queryIBCSwap = new ObservableQueryIbcSwap( - chainGetter, + chainStore, this.queryAssets, this.queryAssetsFromSource, this.queryChains, diff --git a/packages/provider/src/core.ts b/packages/provider/src/core.ts index 7b80bdde6b..22ca25f73f 100644 --- a/packages/provider/src/core.ts +++ b/packages/provider/src/core.ts @@ -87,6 +87,10 @@ export class Keplr implements IKeplr, KeplrCoreTypes { }; } ): Promise { + if (chainInfo.hideInUI) { + throw new Error("hideInUI is not allowed"); + } + if (chainInfo.gasPriceStep) { // Gas price step in ChainInfo is legacy format. // Try to change the recent format for backward-compatibility. diff --git a/packages/provider/src/inject.ts b/packages/provider/src/inject.ts index 9d6388b3a3..f0b8db2772 100644 --- a/packages/provider/src/inject.ts +++ b/packages/provider/src/inject.ts @@ -386,6 +386,10 @@ export class InjectedKeplr implements IKeplr, KeplrCoreTypes { } async experimentalSuggestChain(chainInfo: ChainInfo): Promise { + if (chainInfo.hideInUI) { + throw new Error("hideInUI is not allowed"); + } + if ( chainInfo.features?.includes("stargate") || chainInfo.features?.includes("no-legacy-stdTx") diff --git a/packages/stores/src/chain/base.ts b/packages/stores/src/chain/base.ts index 2aa8f8b58d..7c03be4347 100644 --- a/packages/stores/src/chain/base.ts +++ b/packages/stores/src/chain/base.ts @@ -336,6 +336,10 @@ export class ChainInfoImpl return this._embedded.evm; } + get hideInUI(): boolean | undefined { + return this._embedded.hideInUI; + } + hasFeature(feature: string): boolean { return !!( this._embedded.features && this._embedded.features.includes(feature) diff --git a/packages/stores/src/chain/types.ts b/packages/stores/src/chain/types.ts index 174470dd06..ed1f566e21 100644 --- a/packages/stores/src/chain/types.ts +++ b/packages/stores/src/chain/types.ts @@ -63,4 +63,5 @@ export interface IChainInfoImpl { rpc: string; } | undefined; + readonly hideInUI: boolean | undefined; } diff --git a/packages/types/src/chain-info.ts b/packages/types/src/chain-info.ts index 10fee34d6b..10df6b7251 100644 --- a/packages/types/src/chain-info.ts +++ b/packages/types/src/chain-info.ts @@ -44,6 +44,8 @@ export interface ChainInfo { readonly chainSymbolImageUrl?: string; + readonly hideInUI?: boolean; + readonly evm?: { chainId: number; rpc: string;