From c0d2931ca157cfd782d54d3afe68bedbab4ed5be Mon Sep 17 00:00:00 2001 From: Sam <60031762+kws1207@users.noreply.github.com> Date: Tue, 30 Sep 2025 22:42:01 +0900 Subject: [PATCH 1/9] feat: Add Keplr mobile connector (#1) * feat: Add Keplr mobile connector * feat: Add keplr mobile to package.json exports and vite config * fix: Use user agent for isInKeplrMobileAppBrowser * fix: Add _wallet to KeplrMobileBaseConnector * feat: Add KeplrMobileBaseConnector to defaultConnectors --- package.json | 5 + src/connectors/keplrMobile/constants.ts | 5 + .../keplrMobile/helpers/inAppBrowser.ts | 14 ++ src/connectors/keplrMobile/helpers/index.ts | 1 + src/connectors/keplrMobile/index.ts | 124 ++++++++++++++++++ src/helpers/defaultConnectors.ts | 2 + vite.config.ts | 1 + 7 files changed, 152 insertions(+) create mode 100644 src/connectors/keplrMobile/constants.ts create mode 100644 src/connectors/keplrMobile/helpers/inAppBrowser.ts create mode 100644 src/connectors/keplrMobile/helpers/index.ts create mode 100644 src/connectors/keplrMobile/index.ts diff --git a/package.json b/package.json index e0555385..223ca80c 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,11 @@ "import": "./dist/keplr.js", "require": "./dist/keplr.cjs" }, + "./keplrMobile": { + "types": "./dist/keplrMobile.d.ts", + "import": "./dist/keplrMobile.js", + "require": "./dist/keplrMobile.cjs" + }, "./fordefi": { "types": "./dist/fordefi.d.ts", "import": "./dist/fordefi.js", diff --git a/src/connectors/keplrMobile/constants.ts b/src/connectors/keplrMobile/constants.ts new file mode 100644 index 00000000..ef85ab91 --- /dev/null +++ b/src/connectors/keplrMobile/constants.ts @@ -0,0 +1,5 @@ +export const KEPLR_MOBILE_APP_ICON = ` + + + +` diff --git a/src/connectors/keplrMobile/helpers/inAppBrowser.ts b/src/connectors/keplrMobile/helpers/inAppBrowser.ts new file mode 100644 index 00000000..856534fe --- /dev/null +++ b/src/connectors/keplrMobile/helpers/inAppBrowser.ts @@ -0,0 +1,14 @@ +export const isInKeplrMobileAppBrowser = (): boolean => { + if (typeof window === "undefined") { + return false + } + + const userAgent = navigator.userAgent + const isKeplrMobileApp = userAgent.includes("KeplrWalletMobile") + + if (!isKeplrMobileApp) { + return false + } + + return isKeplrMobileApp +} diff --git a/src/connectors/keplrMobile/helpers/index.ts b/src/connectors/keplrMobile/helpers/index.ts new file mode 100644 index 00000000..bfe3f220 --- /dev/null +++ b/src/connectors/keplrMobile/helpers/index.ts @@ -0,0 +1 @@ +export * from "./inAppBrowser" diff --git a/src/connectors/keplrMobile/index.ts b/src/connectors/keplrMobile/index.ts new file mode 100644 index 00000000..b96891eb --- /dev/null +++ b/src/connectors/keplrMobile/index.ts @@ -0,0 +1,124 @@ +import { type AccountChangeEventHandler } from "@starknet-io/get-starknet-core" +import type { + RequestFnCall, + RpcMessage, + RpcTypeToMessageMap, + StarknetWindowObject, +} from "@starknet-io/types-js" +import type { + AccountInterface, + ProviderInterface, + ProviderOptions, +} from "starknet" +import { + Connector, + type ConnectArgs, + type ConnectorData, + type ConnectorIcons, +} from "../connector" +import { Keplr } from "../injected/keplr" +import { type InjectedConnectorOptions } from "../injected" +import { KEPLR_MOBILE_APP_ICON } from "./constants" +import { isInKeplrMobileAppBrowser } from "./helpers/inAppBrowser" + +export class KeplrMobileBaseConnector extends Connector { + private _wallet: StarknetWindowObject | null = null + + constructor() { + super() + } + + available(): boolean { + return true + } + + async ready(): Promise { + // return true to be compatible with starknet-react + // will need to be implemented + return true + } + + get id(): string { + return "keplrMobile" + } + + get name(): string { + return "Keplr (mobile)" + } + + get icon(): ConnectorIcons { + return { + dark: KEPLR_MOBILE_APP_ICON, + light: KEPLR_MOBILE_APP_ICON, + } + } + + get wallet(): StarknetWindowObject { + throw new Error("not implemented") + } + + async connect(_args: ConnectArgs = {}): Promise { + await this.ensureWallet() + + // will return empty data, connect will only open keplr mobile app + // will require to implement the wallet connection + return { + account: "", + chainId: BigInt(0), + } + } + + async disconnect(): Promise { + throw new Error("not implemented") + } + + async account( + _: ProviderOptions | ProviderInterface, + ): Promise { + throw new Error("not implemented") + } + + async chainId(): Promise { + throw new Error("not implemented") + } + + async request( + call: RequestFnCall, + ): Promise { + throw new Error("not implemented") + } + + // needed, methods required by starknet-react. Otherwise an exception is throwd + async initEventListener(_: AccountChangeEventHandler) { + throw new Error("not implemented") + } + + // needed, methods required by starknet-react. Otherwise an exception is throwd + async removeEventListener(_: AccountChangeEventHandler) { + throw new Error("not implemented") + } + + private async ensureWallet(): Promise { + window.open( + `https://deeplink.keplr.app/web-browser?url=${encodeURIComponent(window.origin)}`, + "_blank", + ) + } +} + +export interface KeplrMobileConnectorInitParams { + inAppBrowserOptions?: Omit +} + +export class KeplrMobileConnector { + static init(params?: KeplrMobileConnectorInitParams): Connector { + const { inAppBrowserOptions } = params || {} + if (isInKeplrMobileAppBrowser()) { + return new Keplr(inAppBrowserOptions) + } else { + return new KeplrMobileBaseConnector() + } + } +} + +export { isInKeplrMobileAppBrowser } diff --git a/src/helpers/defaultConnectors.ts b/src/helpers/defaultConnectors.ts index dee8e3e6..016dae81 100644 --- a/src/helpers/defaultConnectors.ts +++ b/src/helpers/defaultConnectors.ts @@ -1,6 +1,7 @@ import type { StarknetkitConnector } from "../connectors" import { type ArgentMobileConnectorOptions } from "../connectors/argent/argentMobile" import { BraavosMobileBaseConnector } from "../connectors/braavosMobile" +import { KeplrMobileBaseConnector } from "../connectors/keplrMobile" import { ControllerConnector } from "../connectors/controller" import { WebWalletConnector } from "../connectors/webwallet" import { Braavos } from "../connectors/injected/braavos" @@ -43,6 +44,7 @@ export const defaultConnectors = ({ if (isMobileDevice()) { defaultConnectors.push(new BraavosMobileBaseConnector()) + defaultConnectors.push(new KeplrMobileBaseConnector()) } return defaultConnectors diff --git a/vite.config.ts b/vite.config.ts index e16c4300..41e74fb8 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -27,6 +27,7 @@ export default defineConfig({ __dirname, "src/connectors/webwallet/index.ts", ), + keplrMobile: resolve(__dirname, "src/connectors/keplrMobile/index.ts"), argentMobile: resolve( __dirname, "src/connectors/argent/argentMobile/index.ts", From 6dcb706a268eddec02204574ff4e12151dcd04d5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 13 Oct 2025 14:29:19 +0000 Subject: [PATCH 2/9] chore(release): 3.3.0 [skip ci] # [3.3.0](https://github.com/argentlabs/starknetkit/compare/v3.2.0...v3.3.0) (2025-10-13) ### Features * Add Keplr mobile connector ([#1](https://github.com/argentlabs/starknetkit/issues/1)) ([c0d2931](https://github.com/argentlabs/starknetkit/commit/c0d2931ca157cfd782d54d3afe68bedbab4ed5be)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ab3bcb2..fb43a7b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "starknetkit", - "version": "3.2.0", + "version": "3.3.0", "repository": "github:argentlabs/starknetkit", "private": false, "browser": { From 3e21b39f8faea2cb1836eb87e82bfbf8f9037e4a Mon Sep 17 00:00:00 2001 From: Aleksandar Cakalic Date: Thu, 20 Nov 2025 17:55:12 +0100 Subject: [PATCH 3/9] fix: edge case bug when there is only one passed not installed connector --- src/modal/Modal.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modal/Modal.svelte b/src/modal/Modal.svelte index 2ade26fd..8d02e9e3 100644 --- a/src/modal/Modal.svelte +++ b/src/modal/Modal.svelte @@ -98,7 +98,9 @@ if (modalWallets.length === 1) { try { - await callback(modalWallets[0]) + setTimeout(() => { + void callback(modalWallets[0]) + }) } catch (e) { console.error(e) } From 805b0d6b583ab888ca0750faacbd38733cab392a Mon Sep 17 00:00:00 2001 From: Aleksandar Cakalic Date: Thu, 20 Nov 2025 17:55:34 +0100 Subject: [PATCH 4/9] chore: remove redundant code --- src/main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main.ts b/src/main.ts index 4678bf44..a63f8792 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,7 +14,6 @@ import type { StarknetkitConnector, ConnectorData, } from "./connectors" -import { DEFAULT_WEBWALLET_URL } from "./connectors/webwallet/constants" import { ArgentMobileBaseConnector } from "./connectors/argent/argentMobile" import { defaultConnectors } from "./helpers/defaultConnectors" @@ -73,9 +72,6 @@ export const connect = async ({ skipEmit = false, ...restOptions }: ConnectOptionsWithConnectors | ConnectOptions): Promise => { - const { webWalletUrl = DEFAULT_WEBWALLET_URL, argentMobileOptions } = - restOptions as ConnectOptions - const { connectors } = restOptions as ConnectOptionsWithConnectors // force null in case it was disconnected from mobile app From 87212d8c07d33e7d06b0d023fe7a84b4aae5db6d Mon Sep 17 00:00:00 2001 From: Aleksandar Cakalic Date: Thu, 20 Nov 2025 17:58:14 +0100 Subject: [PATCH 5/9] fix: wrong property set on modal wallet --- src/helpers/mapModalWallets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/mapModalWallets.ts b/src/helpers/mapModalWallets.ts index ecd921c3..4962d8f4 100644 --- a/src/helpers/mapModalWallets.ts +++ b/src/helpers/mapModalWallets.ts @@ -54,7 +54,7 @@ export function getModalWallet( id: connector.id, icon: isCompound ? connectorOrCompoundConnector.icon : connector.icon, connector: connectorOrCompoundConnector, - installed: true, + installed: false, title: "title" in connector && isString(connector.title) ? connector.title From 18882a26b1645fbf4e09b26dd52da1f46e442ebc Mon Sep 17 00:00:00 2001 From: Aleksandar Cakalic Date: Thu, 20 Nov 2025 18:00:09 +0100 Subject: [PATCH 6/9] feat: improve case when wallet does not support browser --- src/main.ts | 1 + src/modal/Modal.svelte | 4 ++++ .../DownloadWallet/DownloadWallet.svelte | 19 ++++++++++++++++++- src/modal/layouts/WalletList.svelte | 2 +- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index a63f8792..6bac0917 100644 --- a/src/main.ts +++ b/src/main.ts @@ -244,6 +244,7 @@ export const connect = async ({ }, theme: modalTheme === "system" ? null : (modalTheme ?? null), modalWallets, + discoveryWallets, }, }) as unknown as ModalInstance // Prevents vite build errors }) diff --git a/src/modal/Modal.svelte b/src/modal/Modal.svelte index 8d02e9e3..3d998063 100644 --- a/src/modal/Modal.svelte +++ b/src/modal/Modal.svelte @@ -1,5 +1,6 @@