Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/argent one button connector logic #148

Merged
merged 50 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
14267a7
chore: delete redundant component
Cussone Oct 29, 2024
44ce0a5
chore: inherit `color` for svg icons
Cussone Oct 29, 2024
110bbdf
chore: remove redundant component
Cussone Oct 29, 2024
1202fa3
fix: add missing tailwind's color tokens from `x-ui`
Cussone Oct 29, 2024
f743342
chore: improve button components
Cussone Oct 29, 2024
c777e5d
chore: rename component to more appropriate name
Cussone Oct 29, 2024
8612c92
chore: improve button component
Cussone Oct 29, 2024
9039438
fix: color
Cussone Oct 29, 2024
c57a8d8
feat: add component for rendering icons
Cussone Oct 29, 2024
fba46c4
chore: clean up and add missing functionality
Cussone Oct 29, 2024
6ff294e
fix: pass props and type `downloadLinks`
Cussone Oct 29, 2024
7097abc
chore: replace QR with loader, handle click
Cussone Oct 29, 2024
cc797b7
chore: pass props, adapt usage
Cussone Oct 29, 2024
bb2c00a
chore: connect buttons to handlers
Cussone Oct 29, 2024
3c43169
chore: type wallets, pass props
Cussone Oct 29, 2024
d571de8
feat: programmatically show install extension section
Cussone Oct 30, 2024
e5eecf4
chore: improve method naming
Cussone Oct 30, 2024
61ef1f0
fix: adapt type external
Cussone Oct 30, 2024
ea4008b
feat: create helpers for connectors
Cussone Oct 30, 2024
53d303e
feat: adapt modal to new features
Cussone Oct 30, 2024
015dff2
feat: create modal helpers
Cussone Oct 30, 2024
c743c6d
feat: handle new UI and only QR code approach
Cussone Oct 30, 2024
b3ecb62
chore: add todos
Cussone Oct 30, 2024
35dfa0c
chore: update `closeModal` usage according to API change
Cussone Oct 30, 2024
6903da0
chore: set `Argent` as default
Cussone Oct 30, 2024
6a166b3
chore: update logic to support standalone usage with new UI
Cussone Oct 30, 2024
c2fd50a
chore: add new types
Cussone Oct 30, 2024
50945e5
chore: add new exports
Cussone Oct 30, 2024
e187d3e
chore: handle `StarknetkitCompoundConnector`
Cussone Oct 30, 2024
9166775
chore: handle only qr code approach
Cussone Oct 30, 2024
71b7e6b
chore: add new icons for argent x, improve code
Cussone Oct 30, 2024
3fd36a7
feat: improve type StarknetkitCompoundConnector
Cussone Oct 30, 2024
966a9e7
feat: add new prop to `ConnectOptions`
Cussone Oct 30, 2024
64af087
chore: remove redundant code
Cussone Oct 30, 2024
a76c303
fix: ts error
Cussone Oct 30, 2024
902c3af
chore: update `DEFAULT_WEBWALLET_ICON`
Cussone Oct 30, 2024
0e81651
chore: rename ArgentCompound, update methods/interface, remove redundant
Cussone Oct 30, 2024
def3210
chore: adapt `connect` method to new UI approach
Cussone Oct 30, 2024
56083f4
chore: remove redundant code
Cussone Oct 30, 2024
113a1a3
chore: throw error if html nodes do not exist
Cussone Oct 31, 2024
c23616c
chore: fix ts error
Cussone Oct 31, 2024
7a44258
chore: add installed property to ModalWallet, handle install screen
Cussone Oct 31, 2024
b9acfbc
chore: fix ts error
Cussone Oct 31, 2024
6425b27
chore: improve check
Cussone Oct 31, 2024
e991747
fix: using wrong connector name/icon
Cussone Oct 31, 2024
b3f3ff4
chore: temporarily remove `files`
Cussone Oct 31, 2024
4f1f5a8
chore: fix comment
Cussone Oct 31, 2024
2eb258e
chore: fix vite build errors
Cussone Oct 31, 2024
41ab241
chore: take back `files` prop
Cussone Oct 31, 2024
7a8a75e
chore: add `beta` to push triggered branches
Cussone Oct 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
branches:
- develop
- main
- beta
- hotfix\/v[0-9]+.[0-9]+.[0-9]+

jobs:
Expand Down
19 changes: 12 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,15 @@
"import": "./dist/argentMobile.js",
"require": "./dist/argentMobile.cjs"
},
"./argentCompound": {
"types": "./dist/argentCompound.d.ts",
"import": "./dist/argentCompound.js",
"require": "./dist/argentCompound.cjs"
"./argent": {
"types": "./dist/argent.d.ts",
"import": "./dist/argent.js",
"require": "./dist/argent.cjs"
},
"./argentX": {
"types": "./dist/argentX.d.ts",
"import": "./dist/argentX.js",
"require": "./dist/argentX.cjs"
},
"./braavos": {
"types": "./dist/braavos.d.ts",
Expand All @@ -61,14 +66,14 @@
"main": "./dist/starknetkit.cjs",
"module": "./dist/starknetkit.js",
"types": "./dist/starknetkit.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "vite build",
"check": "svelte-check --tsconfig ./tsconfig.json",
"dev": "vite build --watch"
},
"files": [
"dist"
],
"dependencies": {
"@argent/x-ui": "^1.70.1",
"@starknet-io/get-starknet": "^4.0.0",
Expand Down
27 changes: 21 additions & 6 deletions src/connectors/argent/argentMobile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ import {
type ConnectorData,
type ConnectorIcons,
} from "../../connector"
import { InjectedConnector, InjectedConnectorOptions } from "../../injected"
import { InjectedConnectorOptions } from "../../injected"
import { DEFAULT_ARGENT_MOBILE_ICON, DEFAULT_PROJECT_ID } from "./constants"
import { isInArgentMobileAppBrowser } from "../helpers"
import type { StarknetAdapter } from "./modal/starknet/adapter"
import { ArgentX } from "../../injected/argentX"
import { getModalWallet } from "../../../helpers/mapModalWallets"

export interface ArgentMobileConnectorOptions {
dappName: string
Expand All @@ -41,7 +42,7 @@ export interface ArgentMobileConnectorOptions {
url: string
icons?: string[]
rpcUrl?: string
isCompoundConnector?: boolean
onlyQR?: boolean
}

export class ArgentMobileBaseConnector extends Connector {
Expand Down Expand Up @@ -78,7 +79,7 @@ export class ArgentMobileBaseConnector extends Connector {
}

get name(): string {
return this._options.isCompoundConnector ? "Argent" : "Argent (mobile)" // TODO ditch isCompoundConnector
return "Argent (mobile)"
}

get icon(): ConnectorIcons {
Expand All @@ -95,8 +96,14 @@ export class ArgentMobileBaseConnector extends Connector {
return this._wallet
}

async connect(): Promise<ConnectorData> {
await this.ensureWallet()
async connect(
props:
| {
onlyQRCode?: boolean
}
| undefined,
): Promise<ConnectorData> {
await this.ensureWallet({ onlyQRCode: props?.onlyQRCode })

if (!this._wallet) {
throw new ConnectorNotFoundError()
Expand Down Expand Up @@ -188,7 +195,13 @@ export class ArgentMobileBaseConnector extends Connector {
this._wallet = null
}

private async ensureWallet(): Promise<void> {
private async ensureWallet(
props:
| {
onlyQRCode?: boolean
}
| undefined,
): Promise<void> {
const { getStarknetWindowObject } = await import("./modal")
const { chainId, projectId, dappName, description, url, icons, rpcUrl } =
this._options
Expand All @@ -201,13 +214,15 @@ export class ArgentMobileBaseConnector extends Connector {
: publicRPCNode.testnet)

const options = {
onlyQRCode: props?.onlyQRCode,
chainId: chainId ?? constants.NetworkName.SN_MAIN,
name: dappName,
projectId: projectId ?? DEFAULT_PROJECT_ID,
description,
url,
icons,
rpcUrl: providerRpcUrl,
modalWallet: getModalWallet(this),
}

if (projectId === DEFAULT_PROJECT_ID) {
Expand Down
121 changes: 108 additions & 13 deletions src/connectors/argent/argentMobile/modal/argentModal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { getDevice } from "./getDevice"
import Modal from "../../../../modal/Modal.svelte"
import { Layout, ModalWallet } from "../../../../types/modal"
import { getModalTarget } from "../../../../helpers/modal"
import { StarknetkitConnector } from "../../../connector"

const device = getDevice()

Expand All @@ -7,6 +11,7 @@ export interface RequestArguments {
params?: unknown[] | object
}

// TODO - SK-47 - remove this
const overlayStyle = {
position: "fixed",
top: "0",
Expand All @@ -25,6 +30,7 @@ const overlayStyle = {
fontFamily: "'Barlow', sans-serif",
}

// TODO - SK-47 - remove this
const iframeStyle = {
width: "840px",
height: "540px",
Expand All @@ -40,6 +46,17 @@ const iframeStyle = {
transform: "translate(-50%,-50%)",
}

const iframeStyleOnlyQR = {
width: "245px",
height: "245px",
borderRadius: "40px",
zIndex: "99999",
backgroundColor: "white",
border: "none",
outline: "none",
}

// TODO - SK-47 - remove this
const overlayHtml = `
<div id="argent-mobile-modal-container" style="position: relative">
<iframe class="argent-iframe" allow="clipboard-write"></iframe>
Expand All @@ -52,12 +69,20 @@ const overlayHtml = `
</div>
`

const overlayHtmlOnlyQR = `
<div id="argent-mobile-modal-container" style="position: relative; display: flex; justify-content: center; align-items: center">
<iframe class="argent-iframe" allow="clipboard-write"></iframe>
</div>
`

interface Urls {
readonly desktop: string
readonly ios: string
readonly android: string
}

type ModalWalletExtended = ModalWallet & { dappName: string }

class ArgentModal {
public bridgeUrl = "https://login.argent.xyz"
public mobileUrl = "argent://"
Expand All @@ -67,21 +92,66 @@ class ArgentModal {
private overlay?: HTMLDivElement
private popupWindow?: Window
private closingTimeout?: NodeJS.Timeout
private standaloneConnectorModal?: Modal

public showWalletConnectModal(
wcUri: string,
modalWallet: ModalWalletExtended,
) {
const wcParam = encodeURIComponent(wcUri)
const href = encodeURIComponent(window.location.href)

this.showModal(
{
desktop: `${this.bridgeUrl}?wc=${wcParam}&href=${href}&device=desktop&onlyQR=true`,
ios: `${this.mobileUrl}app/wc?uri=${wcParam}&href=${href}&device=mobile`,
android: `${this.mobileUrl}app/wc?uri=${wcParam}&href=${href}&device=mobile`,
},
modalWallet,
)
}

public showWalletConnectModal(wcUri: string) {
public getWalletConnectQR(wcUri: string) {
const wcParam = encodeURIComponent(wcUri)
const href = encodeURIComponent(window.location.href)

this.showModal({
desktop: `${this.bridgeUrl}?wc=${wcParam}&href=${href}&device=desktop`,
this.getQR({
desktop: `${this.bridgeUrl}?wc=${wcParam}&href=${href}&device=desktop&onlyQR=true`,
ios: `${this.mobileUrl}app/wc?uri=${wcParam}&href=${href}&device=mobile`,
android: `${this.mobileUrl}app/wc?uri=${wcParam}&href=${href}&device=mobile`,
})
}

private getQR(urls: Urls) {
const overlay = document.createElement("div")
const shadow = document.querySelector("#starknetkit-modal-container")

if (shadow?.shadowRoot) {
const slot = shadow.shadowRoot.querySelector(".qr-code-slot")

if (slot) {
slot.innerHTML = overlayHtmlOnlyQR
document.body.appendChild(overlay)
this.overlay = overlay

const iframe = slot.querySelector("iframe") as HTMLIFrameElement
iframe.setAttribute("src", urls.desktop)

for (const [key, value] of Object.entries(iframeStyleOnlyQR)) {
iframe.style[key as any] = value
}
} else {
throw new Error("Cannot find QR code slot")
}
} else {
throw new Error("Cannot find modal")
}
}

// TODO - SK-47 - handle this
public showApprovalModal(_: RequestArguments): void {
if (device === "desktop") {
this.showModal({
this.showModalOld({
desktop: `${this.bridgeUrl}?action=sign`,
ios: "",
android: "",
Expand All @@ -95,26 +165,50 @@ class ArgentModal {
Additionally when there is a signing request triggered by the dapp it will hit the deep link with an incomplete URI,
this should be ignored and not considered valid as it's only used for automatically redirecting the users to approve or reject a signing request.
*/
this.showModal({
this.showModalOld({
desktop: `${this.bridgeUrl}?action=sign&device=desktop&href=${href}`,
ios: `${this.mobileUrl}app/wc/request?href=${href}&device=mobile`,
android: `${this.mobileUrl}app/wc/request?href=${href}&device=mobile`,
})
}

public closeModal(success?: "animateSuccess") {
// TODO - SK-47 - remove this
public closeModal(success?: boolean) {
const modal = this.standaloneConnectorModal
if (success) {
this.overlay
?.querySelector("iframe")
?.contentWindow?.postMessage("argent-login.success", "*")
this.popupWindow?.postMessage("argent-login.success", "*")
this.closingTimeout = setTimeout(this.close, 3400)
modal?.$set({ layout: Layout.success })
setTimeout(() => modal?.$destroy(), 3000)
} else {
this.close()
modal?.$set({ layout: Layout.failure })
}
}

private showModal(urls: Urls) {
private showModal(urls: Urls, modalWallet: ModalWalletExtended) {
this.standaloneConnectorModal = new Modal({
target: getModalTarget(),
props: {
layout: Layout.qrCode,
dappName: modalWallet.dappName,
showBackButton: false,
selectedWallet: modalWallet,
callback: async (wallet: ModalWallet | null) => {
try {
const connector = wallet?.connector as StarknetkitConnector

this.standaloneConnectorModal?.$destroy()
await connector?.connect()
} catch (err) {
this.standaloneConnectorModal?.$set({ layout: Layout.failure })
}
},
},
})

this.getQR(urls)
}

// TODO - SK-47 - remove this
private showModalOld(urls: Urls) {
clearTimeout(this.closingTimeout)
if (this.overlay || this.popupWindow) {
this.close()
Expand Down Expand Up @@ -161,6 +255,7 @@ class ArgentModal {
closeButton.addEventListener("click", () => this.closeModal())
}

// TODO - SK-47 - remove this
private close = () => {
this.overlay?.remove()
this.popupWindow?.close()
Expand Down
24 changes: 17 additions & 7 deletions src/connectors/argent/argentMobile/modal/login.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import SignClient from "@walletconnect/sign-client"
import type { SignClientTypes } from "@walletconnect/types"

import { RpcProvider, constants } from "starknet"

// Using NetworkName as a value.
const Network: typeof constants.NetworkName = constants.NetworkName

import type { NamespaceAdapter, NamespaceAdapterOptions } from "./adapter"
import { argentModal } from "./argentModal"
import { resetWalletConnect } from "../../../../helpers/resetWalletConnect"
import { ModalWallet } from "../../../../types/modal"

// Using NetworkName as a value.
const Network: typeof constants.NetworkName = constants.NetworkName

export interface IArgentLoginOptions {
projectId?: string
Expand All @@ -22,6 +21,8 @@ export interface IArgentLoginOptions {
mobileUrl?: string
modalType?: "overlay" | "window"
walletConnect?: SignClientTypes.Options
onlyQRCode?: boolean
modalWallet?: ModalWallet
}

export const login = async <TAdapter extends NamespaceAdapter>(
Expand All @@ -37,6 +38,8 @@ export const login = async <TAdapter extends NamespaceAdapter>(
url,
icons,
walletConnect,
onlyQRCode,
modalWallet,
}: IArgentLoginOptions,
Adapter: new (options: NamespaceAdapterOptions) => TAdapter,
): Promise<TAdapter | null> => {
Expand Down Expand Up @@ -101,13 +104,20 @@ export const login = async <TAdapter extends NamespaceAdapter>(

// Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing).
if (uri) {
argentModal.showWalletConnectModal(uri)
if (onlyQRCode) {
argentModal.getWalletConnectQR(uri)
} else {
argentModal.showWalletConnectModal(uri, {
...modalWallet,
dappName: name || "",
} as ModalWallet & { dappName: string })
}
argentModal.wcUri = uri

// Await session approval from the wallet.
const session = await approval()
adapter.updateSession(session)
argentModal.closeModal("animateSuccess")
argentModal.closeModal(true)
}

return adapter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export class StarknetAdapter
const chainId = this.formatChainId(this.chainId)
argentModal.showApprovalModal(request)
const response = await this.client.request({ topic, chainId, request })
argentModal.closeModal("animateSuccess")
argentModal.closeModal(true)
return response
} catch (error) {
argentModal.closeModal()
Expand Down
Loading