Skip to content

Commit

Permalink
Merge pull request #2034 from galacticcouncil/feat/solana
Browse files Browse the repository at this point in the history
Feat/solana
  • Loading branch information
jvonasek authored Jan 23, 2025
2 parents 51cdd48 + 9d8c8ee commit 456e5af
Show file tree
Hide file tree
Showing 44 changed files with 1,490 additions and 267 deletions.
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@polkadot/util": "^13.1.1",
"@polkadot/util-crypto": "^13.1.1",
"@polkadot/ui-shared": "^3.1.4",
"@galacticcouncil/xcm-core": "^5.5.0",
"@galacticcouncil/xcm-core": "^6.0.0",
"strip-ansi": "6.0.1",
"string-width": "4.2.2",
"wrap-ansi": "7.0.0",
Expand All @@ -38,18 +38,18 @@
"@emotion/styled": "^11.10.4",
"@ethersproject/address": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@galacticcouncil/apps": "^9.2.1",
"@galacticcouncil/apps": "^10.2.0",
"@galacticcouncil/math-lbp": "^1.0.0",
"@galacticcouncil/math-liquidity-mining": "^1.0.0",
"@galacticcouncil/math-omnipool": "^1.0.0",
"@galacticcouncil/math-stableswap": "^1.0.0",
"@galacticcouncil/math-staking": "^1.0.0",
"@galacticcouncil/math-xyk": "^1.0.0",
"@galacticcouncil/sdk": "^5.1.0",
"@galacticcouncil/ui": "^5.2.3",
"@galacticcouncil/xcm-cfg": "^6.0.1",
"@galacticcouncil/xcm-core": "^5.5.0",
"@galacticcouncil/xcm-sdk": "^7.0.1",
"@galacticcouncil/sdk": "^5.3.0",
"@galacticcouncil/ui": "^5.4.0",
"@galacticcouncil/xcm-cfg": "^7.0.0",
"@galacticcouncil/xcm-core": "^6.0.0",
"@galacticcouncil/xcm-sdk": "^8.0.1",
"@hookform/resolvers": "^3.3.4",
"@lit-labs/react": "^1.1.0",
"@polkadot/api": "14.0.1",
Expand All @@ -68,6 +68,7 @@
"@radix-ui/react-toast": "^1.1.4",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.6",
"@solana/web3.js": "^1.98.0",
"@talismn/connect-wallets": "^1.2.5",
"@tanstack/react-location": "^3.7.4",
"@tanstack/react-query": "^4.14.5",
Expand Down
10 changes: 10 additions & 0 deletions patches/@galacticcouncil+xcm-sdk+8.0.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
diff --git a/node_modules/@galacticcouncil/xcm-sdk/build/types/platforms/substrate/SubstrateService.d.ts b/node_modules/@galacticcouncil/xcm-sdk/build/types/platforms/substrate/SubstrateService.d.ts
index c0e665f..14b6b93 100644
--- a/node_modules/@galacticcouncil/xcm-sdk/build/types/platforms/substrate/SubstrateService.d.ts
+++ b/node_modules/@galacticcouncil/xcm-sdk/build/types/platforms/substrate/SubstrateService.d.ts
@@ -1,4 +1,4 @@
-import '@polkadot/api-augment';
+//import '@polkadot/api-augment';
import { AnyParachain, Asset, AssetAmount, ExtrinsicConfig } from '@galacticcouncil/xcm-core';
import { ApiPromise } from '@polkadot/api';
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
37 changes: 37 additions & 0 deletions src/api/external/ethereum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { chainsMap } from "@galacticcouncil/xcm-cfg"
import { EvmChain } from "@galacticcouncil/xcm-core"
import { useQuery, UseQueryOptions } from "@tanstack/react-query"
import { QUERY_KEYS } from "utils/queryKeys"

export const ethereum = chainsMap.get("ethereum") as EvmChain
export const ethereumNativeToken = ethereum.assetsData.get("eth")!

type TAccountBalance = Awaited<ReturnType<typeof fetchEthereumAccountBalance>>

const fetchEthereumAccountBalance = async (address: string) => {
if (!ethereum.client) throw new Error("Ethereum is not connected")

const provider = ethereum.client.getProvider()
const balance = await provider.getBalance({
address: address as `0x${string}`,
})
return {
amount: balance.toString(),
decimals: ethereumNativeToken.decimals,
symbol: ethereumNativeToken.asset.originSymbol,
}
}

export const useEthereumAccountBalance = (
address: string,
options: UseQueryOptions<TAccountBalance> = {},
) => {
return useQuery<TAccountBalance>(
QUERY_KEYS.ethereumAccountBalance(address),
async () => fetchEthereumAccountBalance(address),
{
enabled: !!address,
...options,
},
)
}
19 changes: 13 additions & 6 deletions src/api/external/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ export const useExternalApi = (chainKey: string) => {
)
}

export const useExternalWhitelist = () => {
return useQuery(
QUERY_KEYS.externalStore,
async () => MetadataStore.getInstance().externalWhitelist(),
{
cacheTime: 1000 * 60 * 60 * 24, // 24 hours,
staleTime: 1000 * 60 * 60 * 1, // 1 hour
},
)
}

/**
* Used for fetching tokens from supported parachains
*/
Expand Down Expand Up @@ -296,11 +307,7 @@ export const useExternalAssetsWhiteList = () => {
const { isExternal, getAsset } = useAssets()
const { isLoaded } = useRpcProvider()
const assetRegistry = useExternalAssetRegistry()

const whitelist = useMemo(
() => MetadataStore.getInstance().externalWhitelist(),
[],
)
const { data: whitelist } = useExternalWhitelist()

const getIsWhiteListed = useCallback(
(assetId: string) => {
Expand All @@ -311,7 +318,7 @@ export const useExternalAssetsWhiteList = () => {
? assetRegistry[+asset.parachainId]?.data?.get(asset.externalId ?? "")
: null

const isManuallyWhiteListed = whitelist.includes(asset.id)
const isManuallyWhiteListed = !!whitelist?.includes(asset.id)
const isWhiteListed =
isManuallyWhiteListed ||
asset?.isWhiteListed ||
Expand Down
36 changes: 36 additions & 0 deletions src/api/external/solana.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { chainsMap } from "@galacticcouncil/xcm-cfg"
import { SolanaChain } from "@galacticcouncil/xcm-core"
import { PublicKey } from "@solana/web3.js"
import { useQuery, UseQueryOptions } from "@tanstack/react-query"
import { QUERY_KEYS } from "utils/queryKeys"

export const solana = chainsMap.get("solana") as SolanaChain
export const solanaNativeToken = solana.assetsData.get("sol")!

type TAccountBalance = Awaited<ReturnType<typeof fetchSolanaAccountBalance>>

const fetchSolanaAccountBalance = async (address: string) => {
if (!solana.connection) throw new Error("Solana is not connected")

const balance = await solana.connection.getBalance(new PublicKey(address))

return {
amount: balance.toString(),
decimals: solanaNativeToken.decimals,
symbol: solanaNativeToken.asset.originSymbol,
}
}

export const useSolanaAccountBalance = (
address: string,
options: UseQueryOptions<TAccountBalance> = {},
) => {
return useQuery<TAccountBalance>(
QUERY_KEYS.solanaAccountBalance(address),
async () => fetchSolanaAccountBalance(address),
{
enabled: !!address,
...options,
},
)
}
4 changes: 2 additions & 2 deletions src/api/vesting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { compareAsc } from "date-fns"
import { useRpcProvider } from "providers/rpcProvider"

export const useVestingSchedules = (address: Maybe<AccountId32 | string>) => {
const { api } = useRpcProvider()
const { api, isLoaded } = useRpcProvider()
return useQuery(
QUERY_KEYS.vestingSchedules(address),
address != null ? getVestingSchedules(api, address) : undefinedNoop,
{ enabled: !!address },
{ enabled: !!address && isLoaded },
)
}

Expand Down
20 changes: 14 additions & 6 deletions src/api/xcm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import {
chainsMap,
routesMap,
validations,
swaps,
HydrationConfigService,
} from "@galacticcouncil/xcm-cfg"
import { SubstrateApis } from "@galacticcouncil/xcm-core"
import { Wallet } from "@galacticcouncil/xcm-sdk"
import { useMutation } from "@tanstack/react-query"
import { Transaction, useStore } from "state/store"
import { isAnyParachain } from "utils/helpers"
import { external } from "@galacticcouncil/apps"
import { TRegisteredAsset } from "sections/wallet/addToken/AddToken.utils"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
Expand All @@ -37,9 +37,7 @@ export const syncAssethubXcmConfig = (
asset: TRegisteredAsset,
config: HydrationConfigService,
) => {
const hubAsset = external.toHubAsset(asset)
const paraAsset = external.toParachainAsset(asset)
config.addExternalHubRoute(hubAsset, paraAsset)
config.registerExternal([asset])
}

export const useCrossChainWallet = () => {
Expand All @@ -52,11 +50,21 @@ export const useCrossChainWallet = () => {
routes: routesMap,
})

return new Wallet({
const wallet = new Wallet({
configService: configService,
poolService: poolService,
transferValidations: validations,
})

// Register chain swaps
const hydration = configService.getChain("hydration")
const assethub = configService.getChain("assethub")

wallet.registerSwaps(
new swaps.HydrationSwap(hydration, poolService),
new swaps.AssethubSwap(assethub),
)

return wallet
}, [poolService])
}

Expand Down
4 changes: 4 additions & 0 deletions src/assets/icons/PhantomLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/assets/icons/SolflareLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 19 additions & 2 deletions src/components/AccountAvatar/AccountAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { JdenticonAvatar } from "./JdenticonAvatar"
import { PolkadotAvatar } from "./PolkadotAvatar"
import { MetaMaskAvatar } from "./MetaMaskAvatar"
import { isEvmAccount, isEvmAddress, safeConvertAddressH160 } from "utils/evm"
import { WalletProviderType } from "sections/web3-connect/constants/providers"
import {
SOLANA_PROVIDERS,
WalletProviderType,
} from "sections/web3-connect/constants/providers"
import { genesisHashToChain } from "utils/helpers"
import type { Icon } from "@polkadot/networks/types"

Expand All @@ -24,12 +27,26 @@ export const AccountAvatar: FC<Props> = (props) => {
const chainIcon: Icon =
props.genesisHash && chain?.icon ? chain.icon : "polkadot"

const isSolana = !!props.provider && SOLANA_PROVIDERS.includes(props.provider)
const isEvm = isEvmAccount(props.address) || isEvmAddress(props.address)

const theme = props.provider?.startsWith("talisman")
? "talisman"
: isEvm
? "evm"
: chainIcon
: isSolana
? "jdenticon"
: chainIcon

if (theme === "jdenticon") {
return (
<JdenticonAvatar
publicKey={props.address}
size={props.size}
className={props.className}
/>
)
}

if (theme === "evm") {
return (
Expand Down
7 changes: 5 additions & 2 deletions src/i18n/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,17 @@
"walletConnect.provider.title": "Connect wallet",
"walletConnect.provider.description.default": "Select your wallet of choice.",
"walletConnect.provider.description.substrate": "Select your Polkadot wallet of choice.",
"walletConnect.provider.description.substrateChain": "Use available Polkadot crypto wallets to connect to {{ chain }}",
"walletConnect.provider.description.substrateChain": "Use available Polkadot crypto wallets to connect to {{ chain }}.",
"walletConnect.provider.description.evm": "Select your Ethereum wallet of choice.",
"walletConnect.provider.description.evmChain": "Use available Ethereum crypto wallets to connect to {{ chain }}",
"walletConnect.provider.description.evmChain": "Use available Ethereum crypto wallets to connect to {{ chain }}.",
"walletConnect.provider.description.solanaChain": "Use available Solana crypto wallets to connect to {{ chain }}.",
"walletConnect.provider.description.invalidWallet": "Connect a Hydration compatible wallet.",
"walletConnect.provider.continue": "Connect",
"walletConnect.provider.download": "Download",
"walletConnect.provider.disconnect": "Disconnect",
"walletConnect.provider.connectAll": "Connect all",
"walletConnect.provider.mode.substrate": "Polkadot",
"walletConnect.provider.mode.solana": "Solana",
"walletConnect.provider.mode.evm": "EVM",
"walletConnect.provider.mode.all": "All",
"walletConnect.provider.section.installed": "Installed & recently used",
Expand Down
3 changes: 3 additions & 0 deletions src/polkadot.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { InjectedWindowProvider } from "@polkadot/extension-inject/types"
import { MetaMaskLikeProvider } from "utils/metamask"
import { SolanaWalletProvider } from "utils/solana"

import BigNumber from "bignumber.js"

Expand All @@ -20,7 +21,9 @@ declare global {
SubWallet?: MetaMaskLikeProvider
phantom?: {
ethereum: MetaMaskLikeProvider
solana: SolanaWalletProvider
}
solflare?: SolanaWalletProvider
injectedWeb3?: Record<string, InjectedWindowProvider>
walletExtension?: { isNovaWallet?: boolean }
}
Expand Down
10 changes: 3 additions & 7 deletions src/sections/pools/PoolsPage.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import { useTVL } from "api/stats"
import { scaleHuman } from "utils/balance"
import { useAccountAssets } from "api/deposits"
import { TAsset, TShareToken, useAssets } from "providers/assets"
import { MetadataStore } from "@galacticcouncil/ui"
import { getTradabilityFromBits } from "api/omnipool"
import { useOmnipoolFarms, useXYKFarms } from "api/farms"
import { useExternalWhitelist } from "api/external"

export const isXYKPoolType = (pool: TPool | TXYKPool): pool is TXYKPool =>
!!(pool as TXYKPool).shareTokenIssuance
Expand Down Expand Up @@ -248,11 +248,7 @@ export const useXYKPools = () => {
const { data: xykConsts } = useXYKConsts()
const { shareTokens } = useAssets()
const { data: accountAssets } = useAccountAssets()

const whitelist = useMemo(
() => MetadataStore.getInstance().externalWhitelist(),
[],
)
const { data: whitelist } = useExternalWhitelist()

const { validShareTokens, allShareTokens } = useMemo(() => {
return shareTokens.reduce<{
Expand All @@ -261,7 +257,7 @@ export const useXYKPools = () => {
}>(
(acc, shareToken) => {
const isInvalid = !shareToken.assets.some(
(asset) => asset.isSufficient || whitelist.includes(asset.id),
(asset) => asset.isSufficient || whitelist?.includes(asset.id),
)

if (!isInvalid) acc.validShareTokens.push(shareToken)
Expand Down
Loading

0 comments on commit 456e5af

Please sign in to comment.