Skip to content

Commit

Permalink
Wallet connect
Browse files Browse the repository at this point in the history
  • Loading branch information
vkulinich-cl committed Jun 22, 2023
1 parent 2f3756c commit 2e0ebab
Show file tree
Hide file tree
Showing 26 changed files with 1,298 additions and 76 deletions.
2 changes: 2 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ VITE_USD_PEGGED_ASSET_NAME=USDT
VITE_USD_PEGGED_ASSET_ID=19
VITE_FF_XCM_ENABLED=true
VITE_ENV=rococo
VITE_WC_PROJECT_ID=8acb5f70a756a0a3bea40322364949c1
VITE_HDX_CAIP_ID=polkadot:a85cfb9b9fd4d622a5b28289a02347af
3 changes: 3 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ VITE_USD_PEGGED_ASSET_NAME=USDT
VITE_USD_PEGGED_ASSET_ID=14
VITE_FF_XCM_ENABLED=true
VITE_ENV=production

VITE_WC_PROJECT_ID=8acb5f70a756a0a3bea40322364949c1
VITE_HDX_CAIP_ID=polkadot:a85cfb9b9fd4d622a5b28289a02347af
2 changes: 2 additions & 0 deletions .env.rococo
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ VITE_USD_PEGGED_ASSET_NAME=USDT
VITE_USD_PEGGED_ASSET_ID=19
VITE_FF_XCM_ENABLED=false
VITE_ENV=rococo
VITE_WC_PROJECT_ID=8acb5f70a756a0a3bea40322364949c1
VITE_HDX_CAIP_ID=polkadot:a85cfb9b9fd4d622a5b28289a02347af
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"@galacticcouncil/ui": "^1.2.12",
"@lit-labs/react": "^1.1.0",
"@polkadot/api": "10.9.1",
"@polkadot/ui-shared": "^3.1.4",
"@polkadot/extension-inject": "^0.44.5",
"@polkadot/ui-shared": "^3.1.4",
"@radix-ui/react-dialog": "^1.0.0",
"@radix-ui/react-dropdown-menu": "^2.0.1",
"@radix-ui/react-label": "^1.0.0",
Expand All @@ -56,6 +56,9 @@
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"@types/uuid": "^8.3.4",
"@walletconnect/qrcode-modal": "^1.8.0",
"@walletconnect/sign-client": "^2.8.1",
"@walletconnect/types": "^2.8.1",
"bignumber.js": "^9.1.0",
"color": "^4.2.3",
"comlink": "^4.3.1",
Expand Down
8 changes: 8 additions & 0 deletions src/assets/icons/WalletConnect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 13 additions & 6 deletions src/components/AddressBook/AddressBook.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { persist } from "zustand/middleware"
export const useWalletAddresses = () => {
const { account } = useAccountStore()
const storageAddresses = useAddressStore()
const providerAddresses = useProviderAddresses(account?.provider)
const providerAddresses = useProviderAccounts(account?.provider)

const data = useMemo(() => {
if (!providerAddresses.data) return []
Expand All @@ -28,11 +28,18 @@ export const useWalletAddresses = () => {
return { data, isLoading: providerAddresses.isLoading }
}

export const useProviderAddresses = (provider: string | undefined) => {
return useQuery(QUERY_KEYS.providerAddresses(provider), async () => {
const wallet = getWalletBySource(provider)
return await wallet?.getAccounts()
})
export const useProviderAccounts = (
provider: string | undefined,
enabled?: boolean,
) => {
return useQuery(
QUERY_KEYS.providerAccounts(provider),
async () => {
const wallet = getWalletBySource(provider)
return await wallet?.getAccounts()
},
{ enabled },
)
}

type Address = { name: string; address: string; provider: string }
Expand Down
27 changes: 15 additions & 12 deletions src/components/AppProviders/AppProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Provider as TooltipProvider } from "@radix-ui/react-tooltip"
import { SkeletonTheme } from "react-loading-skeleton"
import { theme } from "theme"
import { ApiPromise } from "@polkadot/api"
import { WalletConnectProvider } from "components/WalletConnectProvider/WalletConnectProvider"

export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
const preference = useProviderRpcUrlStore()
Expand All @@ -20,18 +21,20 @@ export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
api.data && preference._hasHydrated ? api.data : ({} as ApiPromise)
}
>
<InvalidateOnBlock>
<ToastProvider>
<SkeletonTheme
baseColor={`rgba(${theme.rgbColors.white}, 0.12)`}
highlightColor={`rgba(${theme.rgbColors.white}, 0.24)`}
borderRadius={9999}
>
{children}
<Transactions />
</SkeletonTheme>
</ToastProvider>
</InvalidateOnBlock>
<WalletConnectProvider>
<InvalidateOnBlock>
<ToastProvider>
<SkeletonTheme
baseColor={`rgba(${theme.rgbColors.white}, 0.12)`}
highlightColor={`rgba(${theme.rgbColors.white}, 0.24)`}
borderRadius={9999}
>
{children}
<Transactions />
</SkeletonTheme>
</ToastProvider>
</InvalidateOnBlock>
</WalletConnectProvider>
</ApiPromiseContext.Provider>
</TooltipProvider>
)
Expand Down
80 changes: 80 additions & 0 deletions src/components/WalletConnectProvider/WalletConnectProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { createContext, useContext, useEffect, useMemo, useState } from "react"
import {
BaseWallet,
WalletAggregator,
WalletConnect,
} from "utils/walletConnect"

const walletConnectParams = {
projectId: import.meta.env.VITE_WC_PROJECT_ID,
relayUrl: "wss://relay.walletconnect.com",
metadata: {
name: "Basilisk",
description: "Basilisk",
url: import.meta.env.VITE_DOMAIN_URL,
icons: ["https://walletconnect.com/walletconnect-logo.png"],
},
}

const walletAggregator = new WalletAggregator(
new WalletConnect(walletConnectParams, "HydraDX"),
)

type OnboardProviderProps = { children: JSX.Element }

interface PolkadotWalletsContextProviderProps {
children: JSX.Element
walletAggregator: WalletAggregator
initialWaitMs?: number
}

interface PolkadotWalletsContextProps {
wallet: BaseWallet | undefined
}

const PolkadotWalletsContext = createContext<PolkadotWalletsContextProps>({
wallet: undefined,
})

export const useWalletConnect = () => useContext(PolkadotWalletsContext)

const PolkadotWalletsContextProvider = ({
children,
walletAggregator,
initialWaitMs = 5 /* the default is set to 5ms to give extensions enough lead time to inject their providers */,
}: PolkadotWalletsContextProviderProps) => {
const [wallet, setWallet] = useState<BaseWallet | undefined>()

useEffect(() => {
const timeoutId = setTimeout(async () => {
const wallet = walletAggregator.getWallet()
const isWalletConnected = walletAggregator.getWallet().isConnected()

if (!isWalletConnected) wallet.autoConnect()

setWallet(wallet)
}, initialWaitMs)
return () => clearTimeout(timeoutId)
}, [walletAggregator, initialWaitMs])

const contextData = useMemo(
() => ({
wallet,
}),
[wallet],
)

return (
<PolkadotWalletsContext.Provider value={contextData}>
{children}
</PolkadotWalletsContext.Provider>
)
}

export const WalletConnectProvider = ({ children }: OnboardProviderProps) => {
return (
<PolkadotWalletsContextProvider walletAggregator={walletAggregator}>
{children}
</PolkadotWalletsContextProvider>
)
}
3 changes: 1 addition & 2 deletions src/i18n/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
"and": "and",
"shares": "shares",
"or": "or",
"save": "Save",
"add": "Add",
"error.positive": "Must be positive",
"error.validNumber": "Must be a number",
"error.required": "This field is required",
Expand Down Expand Up @@ -227,6 +225,7 @@
"walletConnect.externalWallet.modal.title": "Add External Account",
"walletConnect.externalWallet.modal.desc": "Paste link to account you would like to monitor.",
"walletConnect.externalWallet.modal.input.placeholder": "Account address here",
"walletConnect.wc": "Wallet Connect",
"wallet.header.assets": "Assets",
"wallet.header.transactions": "Transactions",
"wallet.header.vesting": "Vesting",
Expand Down
4 changes: 3 additions & 1 deletion src/sections/transaction/ReviewTransaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import { ReviewTransactionForm } from "./ReviewTransactionForm"
import { ReviewTransactionPending } from "./ReviewTransactionPending"
import { ReviewTransactionSuccess } from "./ReviewTransactionSuccess"
import { ReviewTransactionToast } from "./ReviewTransactionToast"
import { useWalletConnect } from "components/WalletConnectProvider/WalletConnectProvider"

export const ReviewTransaction: React.FC<Transaction> = (props) => {
const { t } = useTranslation()
const [minimizeModal, setMinimizeModal] = useState(false)

const sendTx = useSendTransactionMutation()
const { wallet } = useWalletConnect()

const modalProps: Partial<ComponentProps<typeof Modal>> =
sendTx.isLoading || sendTx.isSuccess || sendTx.isError
Expand Down Expand Up @@ -85,7 +87,7 @@ export const ReviewTransaction: React.FC<Transaction> = (props) => {
}
{...modalProps}
>
<WalletUpgradeModal />
{!wallet?.isConnected && <WalletUpgradeModal />}
{sendTx.isLoading ? (
<ReviewTransactionPending
txState={sendTx.txState}
Expand Down
35 changes: 23 additions & 12 deletions src/sections/transaction/ReviewTransactionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import BigNumber from "bignumber.js"
import { BN_1 } from "utils/constants"
import { useSpotPrice } from "api/spotPrice"
import { NATIVE_ASSET_ID, POLKADOT_APP_NAME } from "utils/api"
import { useWalletConnect } from "components/WalletConnectProvider/WalletConnectProvider"

export const ReviewTransactionForm = (
props: {
Expand All @@ -34,6 +35,8 @@ export const ReviewTransactionForm = (
const bestNumber = useBestNumber()
const accountCurrency = useAccountCurrency(account?.address)

const { wallet } = useWalletConnect()

const feeMeta = useAssetMeta(
props.overrides?.currencyId ?? accountCurrency.data,
)
Expand All @@ -49,22 +52,30 @@ export const ReviewTransactionForm = (
? PROXY_WALLET_PROVIDER
: account?.provider

const wallet = getWalletBySource(provider)
if (!address) throw new Error("Missing active account")

if (address == null || wallet == null)
throw new Error("Missing active account or wallet")
if (provider === "WalletConnect") {
if (wallet == null) throw new Error("Missing wallet for Wallet Connect")
const signer = wallet.signer
if (!signer) throw new Error("Missing signer for Wallet Connect")

if (props.isProxy) {
await wallet.enable(POLKADOT_APP_NAME)
}
const signature = await props.tx.signAsync(address, { signer, nonce: -1 })
return await props.onSigned(signature)
} else {
const wallet = getWalletBySource(provider)

const signature = await props.tx.signAsync(address, {
signer: wallet.signer,
// defer to polkadot/api to handle nonce w/ regard to mempool
nonce: -1,
})
if (wallet == null) throw new Error("Missing wallet")

return await props.onSigned(signature)
if (props.isProxy) {
await wallet.enable(POLKADOT_APP_NAME)
}
const signature = await props.tx.signAsync(address, {
signer: wallet.signer,
// defer to polkadot/api to handle nonce w/ regard to mempool
nonce: -1,
})
return await props.onSigned(signature)
}
})

const json = getTransactionJSON(props.tx)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getWalletBySource } from "@talismn/connect-wallets"
import { useQuery } from "@tanstack/react-query"
import { Text } from "components/Typography/Text/Text"
import { FC, ReactNode } from "react"
import { useTranslation } from "react-i18next"
import { WalletConnectAccountSelectItem } from "sections/wallet/connect/accountSelect/item/WalletConnectAccountSelectItem"
import { Account, externalWallet } from "state/store"
import { SContainer } from "./WalletConnectAccountSelect.styled"
import { ExternalWalletConnectAccount } from "./external/ExternalWalletConnectAccount"
import { useProviderAccounts } from "components/AddressBook/AddressBook.utils"
import { WalletConnectAccount } from "./wc/WalletConnectAccount"

type Props = {
provider: string
Expand All @@ -21,16 +21,13 @@ export const WalletConnectAccountSelect: FC<Props> = ({
currentAddress,
onClose,
}) => {
const { t } = useTranslation("translation")
const { t } = useTranslation()
const isExternalWallet = provider === externalWallet.provider
const isWalletConnect = provider === "WalletConnect"

const accounts = useQuery(
["web3Accounts", provider],
async () => {
const wallet = getWalletBySource(provider)
return await wallet?.getAccounts()
},
{ enabled: !isExternalWallet },
const accounts = useProviderAccounts(
provider,
!isExternalWallet && !isWalletConnect,
)

const accountComponents = accounts.data?.reduce((memo, account) => {
Expand All @@ -47,7 +44,7 @@ export const WalletConnectAccountSelect: FC<Props> = ({
key={account.address}
name={accountName}
address={account.address}
setAccount={() => {
onClick={() => {
onSelect({
name: accountName,
address: account.address,
Expand Down Expand Up @@ -79,6 +76,11 @@ export const WalletConnectAccountSelect: FC<Props> = ({
address={currentAddress}
onClose={onClose}
/>
) : isWalletConnect ? (
<WalletConnectAccount
currentAddress={currentAddress}
onSelect={onSelect}
/>
) : (
accountComponents
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const ExternalWalletConnectAccount = ({
provider={PROXY_WALLET_PROVIDER}
name={delegate.name ?? "N/A"}
address={address}
setAccount={() => {
onClick={() => {
setAccount({
...account,
delegate: address,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Props = {
address: string
name: string
provider: string
setAccount?: () => void
onClick?: () => void
isProxy?: boolean
}

Expand All @@ -26,7 +26,7 @@ export const WalletConnectAccountSelectItem: FC<Props> = ({
address,
name,
provider,
setAccount,
onClick,
isProxy,
}) => {
const isBasiliskAddress = address[0] === "b"
Expand All @@ -43,7 +43,7 @@ export const WalletConnectAccountSelectItem: FC<Props> = ({

return (
<SContainer isActive={isActive}>
<SSelectItem isActive={isActive} isProxy={!!isProxy} onClick={setAccount}>
<SSelectItem isActive={isActive} isProxy={!!isProxy} onClick={onClick}>
<div sx={{ flex: "row", align: "center", justify: "space-between" }}>
<Text>{name}</Text>
<Text>
Expand Down
Loading

0 comments on commit 2e0ebab

Please sign in to comment.