From 610cdbc0e3997dd5dff034d68ea6e6c500098e8c Mon Sep 17 00:00:00 2001 From: bluecco Date: Fri, 27 Oct 2023 15:37:42 +0200 Subject: [PATCH] fix: update connector and injected connector for starknet-react v2 --- README.md | 13 ++++ src/connectors/connector.ts | 13 +--- src/connectors/injected/index.ts | 103 +++++++++++++++++++++++-------- src/main.ts | 6 +- 4 files changed, 98 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 0bae9a0..7b51fc9 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,19 @@ const wallet = await connect({ modalMode: "neverAsk" }) await disconnect({ clearLastWallet: true }) ``` +## Listen to account change + +```js +const selectedConnectorWallet = getSelectedConnectorWallet() +selectedConnectorWallet.on("accountsChanged", () => { + setWallet(prevState => { + const updatedWallet = { ...prevState } + updatedWallet.account = selectedConnectorWallet.account + return updatedWallet + }) +}) +``` + ## 📕 Guides Guides can be found [here](https://www.starknetkit.com/docs) diff --git a/src/connectors/connector.ts b/src/connectors/connector.ts index 561d9e6..906f0d2 100644 --- a/src/connectors/connector.ts +++ b/src/connectors/connector.ts @@ -1,15 +1,14 @@ import EventEmitter from "eventemitter3" -import type { - AccountChangeEventHandler, - StarknetWindowObject, -} from "get-starknet-core" +import type { StarknetWindowObject } from "get-starknet-core" import type { AccountInterface } from "starknet" /** Connector data. */ export type ConnectorData = { /** Connector account. */ account?: string + /** Connector network. */ + chainId?: bigint } /** Connector events. */ @@ -30,12 +29,6 @@ export abstract class Connector extends EventEmitter { abstract ready?(): Promise abstract connect(): Promise abstract disconnect(): Promise - abstract initEventListener?( - accountChangeCb: AccountChangeEventHandler, - ): Promise - abstract removeEventListener?( - accountChangeCb: AccountChangeEventHandler, - ): Promise abstract account(): Promise /** Unique connector id */ abstract get id(): string diff --git a/src/connectors/injected/index.ts b/src/connectors/injected/index.ts index 1709049..d00ed83 100644 --- a/src/connectors/injected/index.ts +++ b/src/connectors/injected/index.ts @@ -1,9 +1,6 @@ -import type { - AccountChangeEventHandler, - StarknetWindowObject, -} from "get-starknet-core" +import type { StarknetWindowObject } from "get-starknet-core" import { getStarknet } from "get-starknet-core" -import { AccountInterface } from "starknet" +import { AccountInterface, constants } from "starknet" import { ConnectorNotConnectedError, ConnectorNotFoundError, @@ -41,6 +38,64 @@ export class InjectedConnector extends Connector { return await this._wallet.isPreauthorized() } + async chainId(): Promise { + this.ensureWallet() + + if (!this._wallet) { + throw new ConnectorNotConnectedError() + } + + const chainIdHex = await this._wallet.provider.getChainId() + const chainId = BigInt(chainIdHex) + return chainId + } + + private async onAccountsChanged(accounts: string[] | string): Promise { + let account: string | string[] + if (typeof accounts === "string") { + account = accounts + } else { + account = accounts[0] + } + + if (account) { + const chainId = await this.chainId() + this.emit("change", { account, chainId }) + } else { + this.emit("disconnect") + } + } + + private onNetworkChanged(network?: string): void { + switch (network) { + // Argent + case "SN_MAIN": + this.emit("change", { + chainId: BigInt(constants.StarknetChainId.SN_MAIN), + }) + break + case "SN_GOERLI": + this.emit("change", { + chainId: BigInt(constants.StarknetChainId.SN_GOERLI), + }) + break + // Braavos + case "mainnet-alpha": + this.emit("change", { + chainId: BigInt(constants.StarknetChainId.SN_MAIN), + }) + break + case "goerli-alpha": + this.emit("change", { + chainId: BigInt(constants.StarknetChainId.SN_GOERLI), + }) + break + default: + this.emit("change", {}) + break + } + } + async connect(): Promise { await this.ensureWallet() @@ -48,8 +103,9 @@ export class InjectedConnector extends Connector { throw new ConnectorNotFoundError() } + let accounts: string[] try { - await this._wallet.enable({ starknetVersion: "v5" }) + accounts = await this._wallet.enable({ starknetVersion: "v5" }) } catch { // NOTE: Argent v3.0.0 swallows the `.enable` call on reject, so this won't get hit. throw new UserRejectedRequestError() @@ -68,6 +124,21 @@ export class InjectedConnector extends Connector { } */ + if (!this._wallet.isConnected || !accounts) { + // NOTE: Argent v3.0.0 swallows the `.enable` call on reject, so this won't get hit. + throw new UserRejectedRequestError() + } + + this._wallet.on("accountsChanged", async (accounts: string[] | string) => { + await this.onAccountsChanged(accounts) + }) + + this._wallet.on("networkChanged", (network?: string) => { + this.onNetworkChanged(network) + }) + + await this.onAccountsChanged(accounts) + return this._wallet.account } @@ -122,26 +193,6 @@ export class InjectedConnector extends Connector { return this._wallet } - async initEventListener(accountChangeCb: AccountChangeEventHandler) { - await this.ensureWallet() - - if (!this._wallet) { - throw new ConnectorNotConnectedError() - } - - this._wallet.on("accountsChanged", accountChangeCb) - } - - async removeEventListener(accountChangeCb: AccountChangeEventHandler) { - await this.ensureWallet() - - if (!this._wallet) { - throw new ConnectorNotConnectedError() - } - - this._wallet.off("accountsChanged", accountChangeCb) - } - private async ensureWallet() { const starknet = getStarknet() const installed = await starknet.getAvailableWallets() diff --git a/src/main.ts b/src/main.ts index 5799138..dea60ac 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,7 @@ import { mapModalWallets } from "./helpers/mapModalWallets" import Modal from "./modal/Modal.svelte" import type { ConnectOptions, ModalWallet } from "./types/modal" -import { ArgentMobileConnector, Connector } from "./connectors" +import { Connector } from "./connectors" import css from "./theme.css?inline" let selectedConnector: Connector | null = null @@ -110,6 +110,10 @@ export const connect = async ({ }) } +// Should be used after a sucessful connect +export const getSelectedConnectorWallet = () => + selectedConnector ? selectedConnector.wallet : null + export const disconnect = async (options: DisconnectOptions = {}) => { removeStarknetLastConnectedWallet() await selectedConnector.disconnect()