From c5291194021f570570822d6498488d43a08861fa Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Sun, 5 May 2024 16:39:13 -0400 Subject: [PATCH] iframe support --- docs/docs/hooks/useCheckWallet.md | 2 + docs/docs/types/walletType.md | 1 + example/next/ui/connect-button.tsx | 3 ++ example/starter/src/utils/graz.ts | 4 ++ packages/graz/package.json | 2 + .../graz/src/actions/wallet/cosmiframe.ts | 38 +++++++++++++++++++ packages/graz/src/actions/wallet/index.ts | 4 ++ packages/graz/src/hooks/wallet.ts | 1 + packages/graz/src/provider/events.tsx | 6 +++ packages/graz/src/types/wallet.ts | 2 + pnpm-lock.yaml | 28 ++++++++++---- 11 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 packages/graz/src/actions/wallet/cosmiframe.ts diff --git a/docs/docs/hooks/useCheckWallet.md b/docs/docs/hooks/useCheckWallet.md index 34c64dd1..c9f72c24 100644 --- a/docs/docs/hooks/useCheckWallet.md +++ b/docs/docs/hooks/useCheckWallet.md @@ -25,6 +25,7 @@ const { data: isKeplrSupported } = useCheckWallet(WalletType.KEPLR); WC_LEAP_MOBILE = "wc_leap_mobile", WC_COSMOSTATION_MOBILE = "wc_cosmostation_mobile", METAMASK_SNAP_LEAP = "metamask_snap_leap", + COSMIFRAME = "cosmiframe", } ``` @@ -41,6 +42,7 @@ const { data: isKeplrSupported } = useCheckWallet(WalletType.KEPLR); WalletTyoe.WC_LEAP_MOBILE, WalletTyoe.WC_COSMOSTATION_MOBILE, WalletTyoe.METAMASK_SNAP_LEAP, + WalletType.COSMIFRAME, } ``` diff --git a/docs/docs/types/walletType.md b/docs/docs/types/walletType.md index fd6e6440..cf8398cb 100644 --- a/docs/docs/types/walletType.md +++ b/docs/docs/types/walletType.md @@ -49,5 +49,6 @@ enum WalletType { STATION = "station", XDEFI = "xdefi", CAPSULE = "capsule", + COSMIFRAME = "cosmiframe", } ``` diff --git a/example/next/ui/connect-button.tsx b/example/next/ui/connect-button.tsx index fb35dc8d..b69f0b8b 100644 --- a/example/next/ui/connect-button.tsx +++ b/example/next/ui/connect-button.tsx @@ -85,6 +85,9 @@ export const ConnectButton: FC = () => { ) : null} {wallets.capsule ? : null} + {wallets.cosmiframe ? ( + + ) : null} diff --git a/example/starter/src/utils/graz.ts b/example/starter/src/utils/graz.ts index 0a8d527b..0304e97c 100644 --- a/example/starter/src/utils/graz.ts +++ b/example/starter/src/utils/graz.ts @@ -65,4 +65,8 @@ export const listedWallets = { name: "Capsule", imgSrc: "/assets/wallet-icon-capsule.jpg", }, + [WalletType.COSMIFRAME]: { + name: "Cosmiframe", + imgSrc: "", + }, }; diff --git a/packages/graz/package.json b/packages/graz/package.json index ba1bd8d1..f57b7b5c 100644 --- a/packages/graz/package.json +++ b/packages/graz/package.json @@ -42,6 +42,7 @@ "prepublishOnly": "pnpm build" }, "peerDependencies": { + "@cosmjs/amino": "*", "@cosmjs/cosmwasm-stargate": "*", "@cosmjs/launchpad": "*", "@cosmjs/proto-signing": "*", @@ -52,6 +53,7 @@ }, "dependencies": { "@cosmsnap/snapper": "^0.1.29", + "@dao-dao/cosmiframe": "^0.0.4", "@keplr-wallet/cosmos": "^0.12.20", "@keplr-wallet/types": "^0.12.23", "@metamask/providers": "^12.0.0", diff --git a/packages/graz/src/actions/wallet/cosmiframe.ts b/packages/graz/src/actions/wallet/cosmiframe.ts new file mode 100644 index 00000000..b4a0ed43 --- /dev/null +++ b/packages/graz/src/actions/wallet/cosmiframe.ts @@ -0,0 +1,38 @@ +import { Cosmiframe } from "@dao-dao/cosmiframe"; + +import { useGrazInternalStore } from "../../store"; +import type { Wallet } from "../../types/wallet"; + +/** + * Function to return {@link Wallet} object and throws and error if not in an iframe. + * + * @example + * ```ts + * try { + * const cosmiframe = getCosmiframe(); + * } catch (error: Error) { + * console.error(error.message); + * } + * ``` + * + * + */ +export const getCosmiframe = (): Wallet => { + if (window.parent === window.self) { + useGrazInternalStore.getState()._notFoundFn(); + throw new Error("not in iframe"); + } + + const keplr = new Cosmiframe().getKeplrClient(); + + return { + enable: keplr.enable.bind(keplr), + getKey: keplr.getKey.bind(keplr), + getOfflineSigner: keplr.getOfflineSigner.bind(keplr), + getOfflineSignerAuto: keplr.getOfflineSignerAuto.bind(keplr), + getOfflineSignerOnlyAmino: keplr.getOfflineSignerOnlyAmino.bind(keplr), + experimentalSuggestChain: keplr.experimentalSuggestChain.bind(keplr), + signDirect: keplr.signDirect.bind(keplr), + signAmino: keplr.signAmino.bind(keplr), + }; +}; diff --git a/packages/graz/src/actions/wallet/index.ts b/packages/graz/src/actions/wallet/index.ts index 9421b675..598e729e 100644 --- a/packages/graz/src/actions/wallet/index.ts +++ b/packages/graz/src/actions/wallet/index.ts @@ -3,6 +3,7 @@ import { grazSessionDefaultValues, useGrazInternalStore, useGrazSessionStore } f import type { Wallet } from "../../types/wallet"; import { WALLET_TYPES, WalletType } from "../../types/wallet"; import { getCapsule } from "./capsule"; +import { getCosmiframe } from "./cosmiframe"; import { getMetamaskSnapCosmos } from "./cosmos-metamask-snap"; import { getCosmostation } from "./cosmostation"; import { getKeplr } from "./keplr"; @@ -93,6 +94,9 @@ export const getWallet = (type: WalletType = useGrazInternalStore.getState().wal case WalletType.CAPSULE: { return getCapsule(); } + case WalletType.COSMIFRAME: { + return getCosmiframe(); + } default: { throw new Error("Unknown wallet type"); } diff --git a/packages/graz/src/hooks/wallet.ts b/packages/graz/src/hooks/wallet.ts index a32fb19d..1ee43ae4 100644 --- a/packages/graz/src/hooks/wallet.ts +++ b/packages/graz/src/hooks/wallet.ts @@ -30,6 +30,7 @@ export const useActiveWalletType = () => { isMetamaskSnapLeap: x.walletType === WalletType.METAMASK_SNAP_LEAP, isStation: x.walletType === WalletType.STATION, isCapsule: x.walletType === WalletType.CAPSULE, + isCosmiframe: x.walletType === WalletType.COSMIFRAME, }), shallow, ); diff --git a/packages/graz/src/provider/events.tsx b/packages/graz/src/provider/events.tsx index 5a6e6f3f..b4f2b240 100644 --- a/packages/graz/src/provider/events.tsx +++ b/packages/graz/src/provider/events.tsx @@ -3,6 +3,7 @@ import { useEffect } from "react"; import { reconnect } from "../actions/account"; import { checkWallet } from "../actions/wallet"; +import { getCosmiframe } from "../actions/wallet/cosmiframe"; import { getCosmostation } from "../actions/wallet/cosmostation"; import { getKeplr } from "../actions/wallet/keplr"; import { getLeap } from "../actions/wallet/leap"; @@ -87,6 +88,11 @@ export const useGrazEvents = () => { void reconnect({ onError: _onReconnectFailed }); }); } + if (_reconnectConnector === WalletType.COSMIFRAME) { + getCosmiframe().subscription?.(() => { + void reconnect({ onError: _onReconnectFailed }); + }); + } } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/packages/graz/src/types/wallet.ts b/packages/graz/src/types/wallet.ts index 5fce7ca1..4acd4c5a 100644 --- a/packages/graz/src/types/wallet.ts +++ b/packages/graz/src/types/wallet.ts @@ -19,6 +19,7 @@ export enum WalletType { STATION = "station", XDEFI = "xdefi", CAPSULE = "capsule", + COSMIFRAME = "cosmiframe", } export const WALLET_TYPES = [ @@ -35,6 +36,7 @@ export const WALLET_TYPES = [ WalletType.XDEFI, WalletType.CAPSULE, WalletType.METAMASK_SNAP_COSMOS, + WalletType.COSMIFRAME, ]; export type Wallet = Pick< diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bcbdbf67..7b32c0e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -212,6 +212,9 @@ importers: packages/graz: dependencies: + '@cosmjs/amino': + specifier: '*' + version: 0.31.3 '@cosmjs/cosmwasm-stargate': specifier: '*' version: 0.31.0 @@ -230,6 +233,9 @@ importers: '@cosmsnap/snapper': specifier: ^0.1.29 version: 0.1.29 + '@dao-dao/cosmiframe': + specifier: ^0.0.4 + version: 0.0.4(@cosmjs/amino@0.31.3)(@cosmjs/proto-signing@0.31.0) '@keplr-wallet/cosmos': specifier: ^0.12.20 version: 0.12.20 @@ -4497,7 +4503,7 @@ packages: /@cosmjs/cosmwasm-stargate@0.31.0: resolution: {integrity: sha512-l6aX++3LhaAGZO46qIgrrNF40lYhOrdPfl35Z32ks6Wf3mwgbQEZwaxnoGzwUePY7/yaIiEFJ1JO6MlVPZVuag==} dependencies: - '@cosmjs/amino': 0.31.0 + '@cosmjs/amino': 0.31.3 '@cosmjs/crypto': 0.31.0 '@cosmjs/encoding': 0.31.0 '@cosmjs/math': 0.31.0 @@ -4754,7 +4760,7 @@ packages: /@cosmjs/proto-signing@0.31.0: resolution: {integrity: sha512-JNlyOJRkn8EKB9mCthkjr6lVX6eyVQ09PFdmB4/DR874E62dFTvQ+YvyKMAgN7K7Dcjj26dVlAD3f6Xs7YOGDg==} dependencies: - '@cosmjs/amino': 0.31.0 + '@cosmjs/amino': 0.31.3 '@cosmjs/crypto': 0.31.0 '@cosmjs/encoding': 0.31.0 '@cosmjs/math': 0.31.0 @@ -4890,7 +4896,7 @@ packages: resolution: {integrity: sha512-GYhk9lzZPj/QmYHC0VV/4AMoRzVcOP+EnB1YZCoWlBdLuVmpBYKRagJqWIrIwdk1E0gF2ZoESd2TYfdh1fqIpg==} dependencies: '@confio/ics23': 0.6.8 - '@cosmjs/amino': 0.31.0 + '@cosmjs/amino': 0.31.3 '@cosmjs/encoding': 0.31.0 '@cosmjs/math': 0.31.0 '@cosmjs/proto-signing': 0.31.0 @@ -5040,6 +5046,17 @@ packages: ses: 0.18.4 dev: false + /@dao-dao/cosmiframe@0.0.4(@cosmjs/amino@0.31.3)(@cosmjs/proto-signing@0.31.0): + resolution: {integrity: sha512-EmzhIRsuGBZhDIWsWzvPFHpQRnnBRj3Cprhp5xSL+trnd1ESadCbIF8sobgSUHrifnPPvF9DTIrnm5RIbuBKhg==} + peerDependencies: + '@cosmjs/amino': '>= ^0.32' + '@cosmjs/proto-signing': '>= ^0.32' + dependencies: + '@cosmjs/amino': 0.31.3 + '@cosmjs/proto-signing': 0.31.0 + uuid: 9.0.1 + dev: false + /@discoveryjs/json-ext@0.5.7: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} @@ -15429,6 +15446,7 @@ packages: /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + requiresBuild: true dependencies: safer-buffer: 2.1.2 dev: false @@ -23286,7 +23304,3 @@ packages: /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: false - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false