From 7a657efe37e27654fc295b0e35822b8896a44fbe Mon Sep 17 00:00:00 2001 From: bluecco Date: Tue, 5 Nov 2024 14:51:05 +0100 Subject: [PATCH 1/5] feat: braavos mobile connector --- package.json | 5 + src/connectors/braavosMobile/constants.ts | 39 ++++++ .../braavosMobile/helpers/inAppBrowser.ts | 14 +++ src/connectors/braavosMobile/helpers/index.ts | 1 + src/connectors/braavosMobile/index.ts | 117 ++++++++++++++++++ src/helpers/defaultConnectors.ts | 19 +++ src/modal/Modal.svelte | 10 ++ vite.config.ts | 4 + 8 files changed, 209 insertions(+) create mode 100644 src/connectors/braavosMobile/constants.ts create mode 100644 src/connectors/braavosMobile/helpers/inAppBrowser.ts create mode 100644 src/connectors/braavosMobile/helpers/index.ts create mode 100644 src/connectors/braavosMobile/index.ts diff --git a/package.json b/package.json index 8fab9b1..85c73fe 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,11 @@ "import": "./dist/argentMobile.js", "require": "./dist/argentMobile.cjs" }, + "./braavosMobile": { + "types": "./dist/braavosMobile.d.ts", + "import": "./dist/braavosMobile.js", + "require": "./dist/braavosMobile.cjs" + }, "./injected": { "types": "./dist/injectedConnector.d.ts", "import": "./dist/injectedConnector.js", diff --git a/src/connectors/braavosMobile/constants.ts b/src/connectors/braavosMobile/constants.ts new file mode 100644 index 0000000..9cde12b --- /dev/null +++ b/src/connectors/braavosMobile/constants.ts @@ -0,0 +1,39 @@ +export const BRAAVOS_MOBILE_APP_ICON = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +` diff --git a/src/connectors/braavosMobile/helpers/inAppBrowser.ts b/src/connectors/braavosMobile/helpers/inAppBrowser.ts new file mode 100644 index 0000000..18e2237 --- /dev/null +++ b/src/connectors/braavosMobile/helpers/inAppBrowser.ts @@ -0,0 +1,14 @@ +export const isInBraavosMobileAppBrowser = (): boolean => { + if (typeof window === "undefined") { + return false + } + + const userAgent = navigator.userAgent.toLowerCase() + const isBraavosMobileApp = userAgent.includes("braavos") + + if (!isBraavosMobileApp) { + return false + } + + return isBraavosMobileApp +} diff --git a/src/connectors/braavosMobile/helpers/index.ts b/src/connectors/braavosMobile/helpers/index.ts new file mode 100644 index 0000000..bfe3f22 --- /dev/null +++ b/src/connectors/braavosMobile/helpers/index.ts @@ -0,0 +1 @@ +export * from "./inAppBrowser" diff --git a/src/connectors/braavosMobile/index.ts b/src/connectors/braavosMobile/index.ts new file mode 100644 index 0000000..0a24a16 --- /dev/null +++ b/src/connectors/braavosMobile/index.ts @@ -0,0 +1,117 @@ +import { type AccountChangeEventHandler } from "@starknet-io/get-starknet-core" +import { + RequestFnCall, + RpcMessage, + RpcTypeToMessageMap, + type StarknetWindowObject, +} from "@starknet-io/types-js" +import { AccountInterface, ProviderInterface, ProviderOptions } from "starknet" +import { + Connector, + type ConnectorData, + type ConnectorIcons, +} from "../connector" +import { InjectedConnector, InjectedConnectorOptions } from "../injected" +import { isInBraavosMobileAppBrowser } from "./helpers/inAppBrowser" +import { BRAAVOS_MOBILE_APP_ICON } from "./constants" + +export class BraavosMobileBaseConnector 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 "braavosMobile" + } + + get name(): string { + return "Braavos (mobile)" + } + + get icon(): ConnectorIcons { + return { + dark: BRAAVOS_MOBILE_APP_ICON, + light: BRAAVOS_MOBILE_APP_ICON, + } + } + + get wallet(): StarknetWindowObject { + throw new Error("not implemented") + } + + async connect(): Promise { + await this.ensureWallet() + + // will return empty data, connect will only open braavos 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://link.braavos.app/dapp/${window.origin}`, "_blank") + } +} + +export interface BraavosMobileConnectorInitParams { + inAppBrowserOptions?: Omit +} + +export class BraavosMobileConnector { + static init(params?: BraavosMobileConnectorInitParams): Connector { + const { inAppBrowserOptions } = params || {} + if (isInBraavosMobileAppBrowser()) { + return new InjectedConnector({ + options: { id: "braavos", ...inAppBrowserOptions }, + }) + } else { + return new BraavosMobileBaseConnector() + } + } +} + +export { isInBraavosMobileAppBrowser } diff --git a/src/helpers/defaultConnectors.ts b/src/helpers/defaultConnectors.ts index 55119ce..08f5256 100644 --- a/src/helpers/defaultConnectors.ts +++ b/src/helpers/defaultConnectors.ts @@ -3,9 +3,25 @@ import { ArgentMobileBaseConnector, type ArgentMobileConnectorOptions, } from "../connectors/argentMobile" +import { BraavosMobileBaseConnector } from "../connectors/braavosMobile" import { InjectedConnector } from "../connectors/injected" import { WebWalletConnector } from "../connectors/webwallet" +const isMobileDevice = () => { + // Primary method: User Agent + Touch support check + const userAgent = navigator.userAgent.toLowerCase() + const isMobileUA = + /android|webos|iphone|ipad|ipod|blackberry|windows phone/.test(userAgent) + const hasTouchSupport = + "ontouchstart" in window || navigator.maxTouchPoints > 0 + + // Backup method: Screen size + const isSmallScreen = window.innerWidth <= 768 + + // Combine checks: Must match user agent AND (touch support OR small screen) + return isMobileUA && (hasTouchSupport || isSmallScreen) +} + export const defaultConnectors = ({ argentMobileOptions, webWalletUrl, @@ -30,6 +46,9 @@ export const defaultConnectors = ({ } defaultConnectors.push(new ArgentMobileBaseConnector(argentMobileOptions)) + if (isMobileDevice()) { + defaultConnectors.push(new BraavosMobileBaseConnector()) + } defaultConnectors.push(new WebWalletConnector({ url: webWalletUrl })) return defaultConnectors diff --git a/src/modal/Modal.svelte b/src/modal/Modal.svelte index 97a117a..0a4eb27 100644 --- a/src/modal/Modal.svelte +++ b/src/modal/Modal.svelte @@ -53,6 +53,16 @@ return } + const userAgent = navigator.userAgent.toLowerCase() + const isBraavosMobileApp = userAgent.includes("braavos") + + if (isBraavosMobileApp && window?.starknet_braavos) { + try { + callback(new InjectedConnector({ options: { id: "braavos" } })) + } catch {} + return + } + if (modalWallets.length === 1) { try { const [wallet] = modalWallets diff --git a/vite.config.ts b/vite.config.ts index 7496a07..f410258 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -23,6 +23,10 @@ export default defineConfig({ __dirname, "src/connectors/argentMobile/index.ts", ), + braavosMobile: resolve( + __dirname, + "src/connectors/braavosMobile/index.ts", + ), injectedConnector: resolve( __dirname, "src/connectors/injected/index.ts", From 42d4f18f33f304c2e66db434875353849b40aa7a Mon Sep 17 00:00:00 2001 From: bluecco Date: Tue, 5 Nov 2024 14:56:35 +0100 Subject: [PATCH 2/5] chore: release update --- .github/workflows/release.yml | 1 + .releaserc | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 46615dc..e7939be 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,7 @@ on: branches: - develop - main + - beta\/* - hotfix\/v[0-9]+.[0-9]+.[0-9]+ jobs: diff --git a/.releaserc b/.releaserc index b1c7609..cdcb825 100644 --- a/.releaserc +++ b/.releaserc @@ -8,6 +8,10 @@ { "name": "beta", "prerelease": true + }, + { + "name": "beta-braavos-mobile", + "prerelease": true } ], "plugins": [ From ac6fb71f0a84ebfd01820a29b6ed492d491bac85 Mon Sep 17 00:00:00 2001 From: bluecco Date: Tue, 5 Nov 2024 15:05:55 +0100 Subject: [PATCH 3/5] chore: update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e7939be..d1af12a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: branches: - develop - main - - beta\/* + - beta-braavos-mobile - hotfix\/v[0-9]+.[0-9]+.[0-9]+ jobs: From f1f6856a7ec1e4011888554652d75a1bb1596543 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 5 Nov 2024 14:06:42 +0000 Subject: [PATCH 4/5] chore(release): 2.4.0-beta-braavos-mobile.1 [skip ci] # [2.4.0-beta-braavos-mobile.1](https://github.com/argentlabs/starknetkit/compare/v2.3.4...v2.4.0-beta-braavos-mobile.1) (2024-11-05) ### Features * braavos mobile connector ([7a657ef](https://github.com/argentlabs/starknetkit/commit/7a657efe37e27654fc295b0e35822b8896a44fbe)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85c73fe..46b0a8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "starknetkit", - "version": "2.3.4", + "version": "2.4.0-beta-braavos-mobile.1", "repository": "github:argentlabs/starknetkit", "private": false, "browser": { From 99b2e8f28d3bd6e1aa7b95c37f354971d3d6fe98 Mon Sep 17 00:00:00 2001 From: bluecco Date: Tue, 5 Nov 2024 15:52:41 +0100 Subject: [PATCH 5/5] refactor: move check outside onMount in svelte modal --- src/modal/Modal.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modal/Modal.svelte b/src/modal/Modal.svelte index 0a4eb27..b1b00ed 100644 --- a/src/modal/Modal.svelte +++ b/src/modal/Modal.svelte @@ -21,6 +21,9 @@ } let isInAppBrowser = starknetMobile?.isInAppBrowser + const userAgent = navigator.userAgent.toLowerCase() + const isBraavosMobileApp = userAgent.includes("braavos") + const setLoadingItem = (item: string | false) => { loadingItem = item } @@ -53,9 +56,6 @@ return } - const userAgent = navigator.userAgent.toLowerCase() - const isBraavosMobileApp = userAgent.includes("braavos") - if (isBraavosMobileApp && window?.starknet_braavos) { try { callback(new InjectedConnector({ options: { id: "braavos" } }))