From 75522ffb6ba62e7860ff51600fae9ccd8ad9f163 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Sat, 20 Apr 2024 13:47:04 +0700 Subject: [PATCH] capsule integration --- example/next/pages/_app.tsx | 3 +- example/next/pages/index.tsx | 7 +- .../public/assets/wallet-icon-capsule.jpg | Bin 0 -> 6290 bytes example/starter/src/pages/_app.tsx | 9 +++ example/starter/src/pages/index.tsx | 36 +++++++++-- .../starter/src/ui/modal/connect-wallet.tsx | 3 +- example/starter/src/utils/graz.ts | 4 ++ packages/graz/package.json | 4 +- packages/graz/src/actions/account.ts | 47 ++++++++++++-- packages/graz/src/actions/chains.ts | 8 ++- packages/graz/src/actions/wallet/capsule.ts | 61 ++++++++++++++++-- packages/graz/src/hooks/account.ts | 8 +-- packages/graz/src/hooks/capsule.ts | 14 ++-- packages/graz/src/hooks/signingClients.ts | 1 - packages/graz/src/store/index.ts | 7 +- packages/graz/src/types/wallet.ts | 2 +- pnpm-lock.yaml | 14 ++-- 17 files changed, 180 insertions(+), 48 deletions(-) create mode 100644 example/starter/public/assets/wallet-icon-capsule.jpg diff --git a/example/next/pages/_app.tsx b/example/next/pages/_app.tsx index 9f595bea..dccb9589 100644 --- a/example/next/pages/_app.tsx +++ b/example/next/pages/_app.tsx @@ -1,5 +1,4 @@ import { ChakraProvider, extendTheme } from "@chakra-ui/react"; -import { CapsuleEnvironment } from "@leapwallet/cosmos-social-login-capsule-provider"; import { GrazProvider } from "graz"; import type { NextPage } from "next"; import type { AppProps } from "next/app"; @@ -24,7 +23,7 @@ const CustomApp: NextPage = ({ Component, pageProps }) => { }, capsuleConfig: { apiKey: "72c07c099c0f3d8e744bb0754a11726b", - env: CapsuleEnvironment.BETA, + env: "BETA", }, }} > diff --git a/example/next/pages/index.tsx b/example/next/pages/index.tsx index f2228e95..cc23a7ad 100644 --- a/example/next/pages/index.tsx +++ b/example/next/pages/index.tsx @@ -17,7 +17,7 @@ const HomePage: NextPage = () => { const { data: accountData } = useAccount({ chainId: "cosmoshub-4", }); - const { client, modalState, onSuccessfulLogin, setModalState } = useCapsule(); + const { client, modalState, onAfterLoginSuccessful, setModalState, onLoginFailure } = useCapsule(); const { colorMode } = useColorMode(); return (
@@ -47,11 +47,10 @@ const HomePage: NextPage = () => { { - void onSuccessfulLogin?.(); - console.log("login successful"); + void onAfterLoginSuccessful?.(); }} onLoginFailure={() => { - console.log("login failure"); + onLoginFailure(); }} setShowCapsuleModal={setModalState} showCapsuleModal={modalState} diff --git a/example/starter/public/assets/wallet-icon-capsule.jpg b/example/starter/public/assets/wallet-icon-capsule.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2703ea0e5254927fc5dbcd5da2018500acd629c7 GIT binary patch literal 6290 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 G#D4+b1k$Yl literal 0 HcmV?d00001 diff --git a/example/starter/src/pages/_app.tsx b/example/starter/src/pages/_app.tsx index fbd0fb7a..e9fb58c6 100644 --- a/example/starter/src/pages/_app.tsx +++ b/example/starter/src/pages/_app.tsx @@ -29,6 +29,15 @@ const MyApp = ({ Component, pageProps }: AppProps) => { projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID, }, }, + capsuleConfig: { + apiKey: "72c07c099c0f3d8e744bb0754a11726b", + env: "BETA", + }, + walletDefaultOptions: { + sign: { + preferNoSetFee: true, + }, + }, }} > diff --git a/example/starter/src/pages/index.tsx b/example/starter/src/pages/index.tsx index 0165b88c..e96bbb4b 100644 --- a/example/starter/src/pages/index.tsx +++ b/example/starter/src/pages/index.tsx @@ -1,14 +1,38 @@ -import { Stack } from "@chakra-ui/react"; +import { Stack, useColorMode } from "@chakra-ui/react"; +import { useCapsule } from "graz"; +import dynamic from "next/dynamic"; import { Card } from "src/ui/card/chain"; import { mainnetChains } from "src/utils/graz"; +const LeapSocialLogin = dynamic( + () => import("@leapwallet/cosmos-social-login-capsule-provider-ui").then((m) => m.CustomCapsuleModalView), + { ssr: false }, +); + const HomePage = () => { + const { client, modalState, onAfterLoginSuccessful, setModalState, onLoginFailure } = useCapsule(); + + const { colorMode } = useColorMode(); return ( - - {mainnetChains.map((chain) => ( - - ))} - + <> + + {mainnetChains.map((chain) => ( + + ))} + + { + void onAfterLoginSuccessful?.(); + }} + onLoginFailure={() => { + onLoginFailure(); + }} + setShowCapsuleModal={setModalState} + showCapsuleModal={modalState} + theme={colorMode} + /> + ); }; diff --git a/example/starter/src/ui/modal/connect-wallet.tsx b/example/starter/src/ui/modal/connect-wallet.tsx index 7b3ba4b7..77097042 100644 --- a/example/starter/src/ui/modal/connect-wallet.tsx +++ b/example/starter/src/ui/modal/connect-wallet.tsx @@ -2,6 +2,7 @@ import { Button, Heading, HStack, + Image, Modal, ModalBody, ModalContent, @@ -52,7 +53,7 @@ const WalletModal = ({ p={4} spacing={4} > - {/* {wallet.name} */} + {wallet.name} {wallet.name} ))} diff --git a/example/starter/src/utils/graz.ts b/example/starter/src/utils/graz.ts index 5433c120..9e993b12 100644 --- a/example/starter/src/utils/graz.ts +++ b/example/starter/src/utils/graz.ts @@ -57,4 +57,8 @@ export const listedWallets = { imgSrc: "/assets/wallet-icon-cosmostation.png", mobile: true, }, + [WalletType.CAPSULE]: { + name: "Capsule", + imgSrc: "/assets/wallet-icon-capsule.jpg", + }, }; diff --git a/packages/graz/package.json b/packages/graz/package.json index c90843ad..bff61d32 100644 --- a/packages/graz/package.json +++ b/packages/graz/package.json @@ -49,7 +49,7 @@ "@cosmjs/tendermint-rpc": "*", "@leapwallet/cosmos-social-login-capsule-provider": "^0.0.30", "@leapwallet/cosmos-social-login-capsule-provider-ui": "^0.0.47", - "long": "*", + "long": "^4", "react": ">=17" }, "peerDependenciesMeta": { @@ -72,7 +72,7 @@ "cac": "^6.7.14", "cosmos-directory-client": "0.0.6", "wadesta": "^0.0.5", - "zustand": "^4.4.1" + "zustand": "^4.5.2" }, "devDependencies": { "@types/node": "^18.17.15", diff --git a/packages/graz/src/actions/account.ts b/packages/graz/src/actions/account.ts index 64982b13..9853b377 100644 --- a/packages/graz/src/actions/account.ts +++ b/packages/graz/src/actions/account.ts @@ -26,14 +26,12 @@ export const connect = async (args?: ConnectArgs): Promise => { const { recentChainIds: recentChains, chains, walletType } = useGrazInternalStore.getState(); const currentWalletType = args?.walletType || walletType; - const isWalletAvailable = checkWallet(currentWalletType); if (!isWalletAvailable) { throw new Error(`${currentWalletType} is not available`); } const wallet = getWallet(currentWalletType); - const chainIds = typeof args?.chainId === "string" ? [args.chainId] : args?.chainId || recentChains; if (!chainIds) { throw new Error("No last known connected chain, connect action requires chain ids"); @@ -60,10 +58,51 @@ export const connect = async (args?: ConnectArgs): Promise => { const { accounts: _account } = useGrazSessionStore.getState(); await wallet.init?.(); + if ( + isCapsule(currentWalletType) && + useGrazSessionStore.getState().capsuleClient && + Object.values(useGrazSessionStore.getState().accounts || []).length > 0 + ) { + const connectedChains = chainIds.map((x) => chains!.find((y) => y.chainId === x)!); + const _resAcc = useGrazSessionStore.getState().accounts; + useGrazSessionStore.setState({ status: "connecting" }); + + const key = await wallet.getKey(chainIds[0]!); + const resultAcccounts: Record = {}; + chainIds.forEach((chainId) => { + resultAcccounts[chainId] = { + ...key, + bech32Address: toBech32( + chains!.find((x) => x.chainId === chainId)!.bech32Config.bech32PrefixAccAddr, + fromBech32(key.bech32Address).data, + ), + }; + }); + useGrazSessionStore.setState((prev) => ({ + accounts: { ...(prev.accounts || {}), ...resultAcccounts }, + })); + + useGrazInternalStore.setState((prev) => ({ + recentChainIds: [...(prev.recentChainIds || []), ...chainIds].filter((thing, i, arr) => { + return arr.indexOf(thing) === i; + }), + })); + useGrazSessionStore.setState((prev) => ({ + activeChainIds: [...(prev.activeChainIds || []), ...chainIds].filter((thing, i, arr) => { + return arr.indexOf(thing) === i; + }), + })); + useGrazSessionStore.setState({ + status: "connected", + }); + return { accounts: _resAcc!, walletType: currentWalletType, chains: connectedChains }; + } await wallet.enable(chainIds); if (isCapsule(currentWalletType)) { - // ignore the return value - throw new Error("CAPSULE_OPEN_MODAL"); + const connectedChains = chainIds.map((x) => chains!.find((y) => y.chainId === x)!); + const _resAcc = useGrazSessionStore.getState().accounts; + useGrazSessionStore.setState({ status: "connecting" }); + return { accounts: _resAcc!, walletType: currentWalletType, chains: connectedChains }; } if (!isWalletConnect(currentWalletType)) { const key = await wallet.getKey(chainIds[0]!); diff --git a/packages/graz/src/actions/chains.ts b/packages/graz/src/actions/chains.ts index 37ab8474..5ca4e8f4 100644 --- a/packages/graz/src/actions/chains.ts +++ b/packages/graz/src/actions/chains.ts @@ -1,7 +1,7 @@ import type { ChainInfo } from "@keplr-wallet/types"; import { useGrazInternalStore } from "../store"; -import type { WalletType } from "../types/wallet"; +import { WalletType } from "../types/wallet"; import type { ConnectResult } from "./account"; import { connect } from "./account"; import { getWallet } from "./wallet"; @@ -34,7 +34,11 @@ export interface SuggestChainArgs { export const suggestChain = async ({ chainInfo, walletType }: SuggestChainArgs): Promise => { const wallet = getWallet(walletType); - await wallet.experimentalSuggestChain(chainInfo); + if (walletType === WalletType.CAPSULE) { + await connect({ chainId: chainInfo.chainId, walletType }); + } else { + await wallet.experimentalSuggestChain(chainInfo); + } return chainInfo; }; diff --git a/packages/graz/src/actions/wallet/capsule.ts b/packages/graz/src/actions/wallet/capsule.ts index 94446db8..d0f015a0 100644 --- a/packages/graz/src/actions/wallet/capsule.ts +++ b/packages/graz/src/actions/wallet/capsule.ts @@ -1,9 +1,11 @@ +import type { AminoSignResponse } from "@cosmjs/amino"; import { fromBech32, toBech32 } from "@cosmjs/encoding"; -import type { Key } from "@keplr-wallet/types"; +import type { DirectSignResponse } from "@cosmjs/proto-signing"; +import type { Keplr, Key } from "@keplr-wallet/types"; import { RECONNECT_SESSION_KEY } from "../../constant"; import { useGrazInternalStore, useGrazSessionStore } from "../../store"; -import type { Wallet } from "../../types/wallet"; +import type { SignAminoParams, SignDirectParams, Wallet } from "../../types/wallet"; import { WalletType } from "../../types/wallet"; export const getCapsule = (): Wallet => { @@ -30,7 +32,7 @@ export const getCapsule = (): Wallet => { useGrazInternalStore.setState({ capsuleState: { showModal: true, chainId } }); }; - const onSuccessLogin = async () => { + const onAfterLoginSuccessful = async () => { const client = useGrazSessionStore.getState().capsuleClient; const { chains } = useGrazInternalStore.getState(); if (!client) throw new Error("Capsule client is not initialized"); @@ -103,12 +105,63 @@ export const getCapsule = (): Wallet => { return client.getOfflineSigner(chainId); }; + const getOfflineSignerAmino = (chainId: string) => { + const client = useGrazSessionStore.getState().capsuleClient; + if (!client) throw new Error("Capsule client is not initialized"); + return client.getOfflineSignerAmino(chainId); + }; + + const getOfflineSignerDirect = (chainId: string) => { + const client = useGrazSessionStore.getState().capsuleClient; + if (!client) throw new Error("Capsule client is not initialized"); + return client.getOfflineSignerDirect(chainId); + }; + + // eslint-disable-next-line @typescript-eslint/require-await + const getOfflineSignerAuto = async (chainId: string) => { + const client = useGrazSessionStore.getState().capsuleClient; + if (!client) throw new Error("Capsule client is not initialized"); + return client.getOfflineSignerDirect(chainId); + }; + + const signDirect = async (...args: SignDirectParams): Promise => { + const [chainId, signer, signDoc] = args; + const client = useGrazSessionStore.getState().capsuleClient; + if (!client) throw new Error("Capsule client is not initialized"); + return client.signDirect(chainId, signer, { + bodyBytes: signDoc.bodyBytes!, + authInfoBytes: signDoc.authInfoBytes!, + chainId: signDoc.chainId!, + accountNumber: signDoc.accountNumber!, + }) as Promise; + }; + + const signAmino = async (...args: SignAminoParams): Promise => { + const [chainId, signer, signDoc, signOptions] = args; + const client = useGrazSessionStore.getState().capsuleClient; + if (!client) throw new Error("Capsule client is not initialized"); + return client.signAmino(chainId, signer, signDoc, signOptions) as Promise; + }; + + const experimentalSuggestChain = async (..._args: Parameters) => { + await Promise.reject(new Error("Capsule does not support experimentalSuggestChain")); + }; + return { init, enable, - onSuccessLogin, + onAfterLoginSuccessful, getKey, + getOfflineSignerAuto, + getOfflineSignerDirect, + signDirect, + signAmino, + experimentalSuggestChain, + setDefaultOptions: () => { + console.log("setDefaultOptions not supported by capsule"); + }, // @ts-expect-error - CapsuleAminoSigner | OfflineDirectSigner getOfflineSigner, + getOfflineSignerAmino, }; }; diff --git a/packages/graz/src/hooks/account.ts b/packages/graz/src/hooks/account.ts index 7a6c75b8..8e2d6ea2 100644 --- a/packages/graz/src/hooks/account.ts +++ b/packages/graz/src/hooks/account.ts @@ -273,13 +273,7 @@ export type UseConnectChainArgs = MutationEventArgs; export const useConnect = ({ onError, onLoading, onSuccess }: UseConnectChainArgs = {}) => { const queryKey = ["USE_CONNECT", onError, onLoading, onSuccess]; const mutation = useMutation(queryKey, connect, { - onError: (err, args) => - Promise.resolve(() => { - // @ts-expect-error - ignore - if (err?.message !== "CAPSULE_OPEN_MODAL") { - onError?.(err, args); - } - }), + onError: (err, args) => onError?.(err, args), onMutate: onLoading, onSuccess: (connectResult) => Promise.resolve(onSuccess?.(connectResult)), }); diff --git a/packages/graz/src/hooks/capsule.ts b/packages/graz/src/hooks/capsule.ts index 243bdd40..6a47f3fc 100644 --- a/packages/graz/src/hooks/capsule.ts +++ b/packages/graz/src/hooks/capsule.ts @@ -1,3 +1,4 @@ +import { disconnect } from "../actions/account"; import { getCapsule } from "../actions/wallet/capsule"; import { useGrazInternalStore, useGrazSessionStore } from "../store"; @@ -7,14 +8,19 @@ export const useCapsule = () => { const capsule = getCapsule(); return { - setModalState: (state: boolean) => - useGrazInternalStore.setState({ + setModalState: (state: boolean) => { + useGrazInternalStore.setState((prev) => ({ capsuleState: { showModal: state, + chainId: prev.capsuleState?.chainId, }, - }), + })); + }, modalState: Boolean(capsuleState?.showModal), client: capsuleClient, - onSuccessfulLogin: capsule.onSuccessLogin, + onAfterLoginSuccessful: capsule.onAfterLoginSuccessful, + onLoginFailure: () => { + void disconnect(); + }, }; }; diff --git a/packages/graz/src/hooks/signingClients.ts b/packages/graz/src/hooks/signingClients.ts index a8c6b43c..43e84ff7 100644 --- a/packages/graz/src/hooks/signingClients.ts +++ b/packages/graz/src/hooks/signingClients.ts @@ -64,7 +64,6 @@ export function useStargateSigningClient( () => ["USE_STARGATE_SIGNING_CLIENT", chains, wallet, args, activeChainIds] as const, [activeChainIds, args, chains, wallet], ); - return useQuery({ queryKey, queryFn: async ({ queryKey: [, _chains, _wallet] }) => { diff --git a/packages/graz/src/store/index.ts b/packages/graz/src/store/index.ts index 5004b12a..f093e2ee 100644 --- a/packages/graz/src/store/index.ts +++ b/packages/graz/src/store/index.ts @@ -1,5 +1,5 @@ import type { ChainInfo, Keplr, Key } from "@keplr-wallet/types"; -import type { CapsuleEnvironment, CapsuleProvider } from "@leapwallet/cosmos-social-login-capsule-provider"; +import type { CapsuleProvider } from "@leapwallet/cosmos-social-login-capsule-provider"; import type { ISignClient, SignClientTypes } from "@walletconnect/types"; import type { Web3ModalConfig } from "@web3modal/standalone"; import { create } from "zustand"; @@ -25,7 +25,7 @@ export interface WalletConnectStore { export interface CapsuleConfig { apiKey: string; - env: CapsuleEnvironment; + env: "DEV" | "SANDBOX" | "BETA" | "PROD"; } export interface CapsuleState { @@ -64,7 +64,7 @@ export type GrazSessionPersistedStore = Pick; export const grazInternalDefaultValues: GrazInternalStore = { @@ -110,6 +110,7 @@ const persistOptions: PersistOptions Promise; disable?: (chainIds?: string | undefined) => Promise; setDefaultOptions?: (options: KeplrIntereactionOptions) => void; - onSuccessLogin?: () => Promise; + onAfterLoginSuccessful?: () => Promise; }; export type SignDirectParams = Parameters; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b57beda..4072675c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -273,14 +273,14 @@ importers: specifier: 0.0.6 version: 0.0.6 long: - specifier: '*' + specifier: ^4 version: 4.0.0 wadesta: specifier: ^0.0.5 version: 0.0.5(long@4.0.0) zustand: - specifier: ^4.4.1 - version: 4.4.1(@types/react@18.2.21)(react@18.2.0) + specifier: ^4.5.2 + version: 4.5.2(@types/react@18.2.21)(react@18.2.0) devDependencies: '@types/node': specifier: ^18.17.15 @@ -9801,7 +9801,7 @@ packages: eventemitter3: 4.0.7 typescript: 5.2.2 viem: 1.5.3(typescript@5.2.2)(zod@3.20.6) - zustand: 4.4.1(@types/react@18.2.21)(react@18.2.0) + zustand: 4.5.2(@types/react@18.2.21)(react@18.2.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -23453,12 +23453,12 @@ packages: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} dev: false - /zustand@4.4.1(@types/react@18.2.21)(react@18.2.0): - resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==} + /zustand@4.5.2(@types/react@18.2.21)(react@18.2.0): + resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==} engines: {node: '>=12.7.0'} peerDependencies: '@types/react': '>=16.8' - immer: '>=9.0' + immer: '>=9.0.6' react: '>=16.8' peerDependenciesMeta: '@types/react':