From 295863b080d28e044a36665e0ccd78684e058e0a Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Tue, 3 Oct 2023 15:14:10 +0530 Subject: [PATCH 01/17] [FEAT] Implementing a base event architecture for Wallet01 Client, restructuring the store --- packages/core/src/client/client.ts | 124 +++++++----------- packages/core/src/client/store.ts | 81 +++++------- packages/core/src/index.ts | 23 +--- packages/core/src/store/createAccountSlice.ts | 8 +- packages/core/src/store/createClientSlice.ts | 18 +-- packages/core/src/store/createWalletSlice.ts | 6 +- packages/core/src/store/rootStore.ts | 14 +- packages/core/src/store/storeTypes.ts | 20 ++- packages/core/src/types/BaseConnector.ts | 49 +++++++ packages/core/src/types/TProvider.ts | 1 - packages/core/src/types/baseConnector.ts | 41 ------ packages/core/src/types/events.ts | 27 ++++ packages/core/src/types/index.ts | 16 +-- packages/core/src/types/methodTypes.ts | 45 +++++++ .../core/src/utils/EnhancedEventEmitter.ts | 79 +++++++++++ packages/core/src/utils/errors.ts | 3 + packages/core/src/utils/index.ts | 6 + packages/core/src/utils/util.ts | 6 - packages/core/tsup.config.ts | 2 +- 19 files changed, 331 insertions(+), 238 deletions(-) create mode 100644 packages/core/src/types/BaseConnector.ts delete mode 100644 packages/core/src/types/TProvider.ts delete mode 100644 packages/core/src/types/baseConnector.ts create mode 100644 packages/core/src/types/events.ts create mode 100644 packages/core/src/types/methodTypes.ts create mode 100644 packages/core/src/utils/EnhancedEventEmitter.ts create mode 100644 packages/core/src/utils/errors.ts create mode 100644 packages/core/src/utils/index.ts delete mode 100644 packages/core/src/utils/util.ts diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index d4f7156..b08fe86 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -1,100 +1,78 @@ -import { BaseConnector } from "../types"; +import { ClientEvents, ConnectorEvents } from "../types/events"; +import { ClientConfig } from "../types/methodTypes"; +import { EnhancedEventEmitter } from "../utils/EnhancedEventEmitter"; import { Wallet01Store } from "./store"; -type ClientConfig = { - autoConnect?: boolean; - connectors: BaseConnector[]; -}; +export default class Wallet01Client extends EnhancedEventEmitter< + ClientEvents & ConnectorEvents +> { + static #instance: Wallet01Client; -export default class Client extends Wallet01Store { - private static instance: Client; - activeConnector: BaseConnector | null = null; + public store: Wallet01Store = Wallet01Store.init(); - constructor({ autoConnect, connectors }: ClientConfig) { + constructor({ autoConnect = false, connectors }: ClientConfig) { super(); - this.setAutoConnect(autoConnect || false); - this.setConnectors(connectors); + + this.store.setConnectors(connectors); if (localStorage.getItem("autoConnect") === null) localStorage.setItem("autoConnect", String(autoConnect)); - if (localStorage.getItem("autoConnect") === "false") - this.setIsAutoConnecting(false); + if (localStorage.getItem("autoConnect") === "false") { + return; + } if (localStorage.getItem("autoConnect") !== String(autoConnect)) localStorage.setItem("autoConnect", String(autoConnect)); - if (!localStorage.getItem("lastUsedConnector")) - this.setIsAutoConnecting(false); + if (!localStorage.getItem("lastUsedConnector")) { + return; + } if ( localStorage.getItem("lastUsedConnector") && localStorage.getItem("autoConnect") === "true" ) { - this.ac(); + this.autoConnect(); } } static init = (config: ClientConfig) => { - if (!Client.instance) Client.instance = new Client(config); - return Client.instance; + if (!Wallet01Client.#instance) + Wallet01Client.#instance = new Wallet01Client(config); + return Wallet01Client.#instance; }; - private async ac() { - try { - this.setIsAutoConnecting(true); - const lastConnName = localStorage.getItem("lastUsedConnector"); - if (!lastConnName) { - this.setIsAutoConnecting(false); - return; - } - - const connector = this.getConnectors().find( - conn => conn.name === lastConnName - ); - - if (!connector) { - this.setIsAutoConnecting(false); - return; - } else this.setLastUsedConnector(connector); - - this.setActiveConnector(this.getLastUsedConnector()); - this.activeConnector = this.getLastUsedConnector(); - - if (this.activeConnector) { - await this.activeConnector.connect({}); - const addresses = await this.activeConnector.getAccount(); - - const address = addresses[0]; - - if (!address) return; - - this.setAddress(address); - - const did = await this.activeConnector - .resolveDid(address) - .catch(err => { - console.error({ error: err }); - return null; - }); - - this.setDid(did); - - const chain = this.activeConnector.getChainId - ? await this.activeConnector.getChainId() - : null; - - this.setChainId(chain); - - this.setActiveChain(this.activeConnector.activeChain); - this.setIsAutoConnecting(false); - this.setIsConnected(true); - } else { - this.setIsAutoConnecting(false); - } - } catch (error) { - console.error({ error }); - this.setIsAutoConnecting(false); + private async autoConnect() { + const lastUsedConnectorName = localStorage.getItem("lastUsedConnector"); + + if (!lastUsedConnectorName) { + console.info({ + message: "No last used connector found", + }); + return; + } + + const lastUsedConnector = this.store + .getConnectors() + .find(conn => conn.name === lastUsedConnectorName); + + if (!lastUsedConnector) { + console.warn({ + message: `The connector for wallet name: ${lastUsedConnectorName} was not found in the list of connectors`, + }); + return; + } + + this.store.setActiveConnector(lastUsedConnector); + + const activeConnector = this.store.getActiveConnector(); + + if (activeConnector) { + this.emit("isAutoConnecting", activeConnector.ecosystem, activeConnector); + + await activeConnector.init(); + await activeConnector.connect(); } } } diff --git a/packages/core/src/client/store.ts b/packages/core/src/client/store.ts index e199a0d..da87c1c 100644 --- a/packages/core/src/client/store.ts +++ b/packages/core/src/client/store.ts @@ -1,17 +1,38 @@ -import getState from "../store/rootStore"; +import { getState } from "../store/rootStore"; +import { IState } from "../store/storeTypes"; import { BaseConnector } from "../types"; export class Wallet01Store { - getActiveChain(): "ethereum" | "solana" | "cosmos" | "tezos" | null { - const { activeChain } = getState(); - return activeChain; + static #instance: Wallet01Store; + + constructor() { + this.getState = getState; + } + + public static init() { + if (!Wallet01Store.#instance) { + Wallet01Store.#instance = new Wallet01Store(); + } + return Wallet01Store.#instance; + } + + getState: () => IState; + + getEcosystem() { + const { ecosystem } = getState(); + return ecosystem; } - getAddress(): string | null { + getAddress() { const { address } = getState(); return address; } + getAddresses() { + const { addresses } = getState(); + return addresses; + } + getDid(): string | null { const { did } = getState(); return did; @@ -27,11 +48,6 @@ export class Wallet01Store { return chainId; } - getAutoConnect(): boolean { - const { autoConnect } = getState(); - return autoConnect; - } - getConnectors(): BaseConnector[] { const { connectors } = getState(); return connectors; @@ -42,65 +58,38 @@ export class Wallet01Store { return activeConnector; } - getLastUsedConnector(): BaseConnector | null { - const { lastUsedConnector } = getState(); - return lastUsedConnector; + setEcosystem(ecosystem: "ethereum" | "solana" | "cosmos" | "tezos") { + const { setEcosystem } = getState(); + setEcosystem(ecosystem); } - getIsAutoConnecting(): boolean { - const { isAutoConnecting } = getState(); - return isAutoConnecting; - } - - setActiveChain( - activeChain: "ethereum" | "solana" | "cosmos" | "tezos" | null - ): void { - const { setActiveChain } = getState(); - setActiveChain(activeChain); - } - - setAddress(address: string | null): void { + setAddress(address: string | null) { const { setAddress } = getState(); setAddress(address); } - setDid(did: string | null): void { + setDid(did: string | null) { const { setDid } = getState(); setDid(did); } - setIsConnected(val: boolean): void { + setIsConnected(val: boolean) { const { setIsConnected } = getState(); setIsConnected(val); } - setChainId(id: string | null): void { + setChainId(id: string | "default") { const { setChainId } = getState(); setChainId(id); } - setAutoConnect(val: boolean): void { - const { setAutoConnect } = getState(); - setAutoConnect(val); - } - - setConnectors(connectors: BaseConnector[]): void { + setConnectors(connectors: BaseConnector[]) { const { setConnectors } = getState(); setConnectors(connectors); } - setActiveConnector(connector: BaseConnector | null): void { + setActiveConnector(connector: BaseConnector | null) { const { setActiveConnector } = getState(); setActiveConnector(connector); } - - setLastUsedConnector(connector: BaseConnector | null): void { - const { setLastUsedConnector } = getState(); - setLastUsedConnector(connector); - } - - setIsAutoConnecting(val: boolean): void { - const { setIsAutoConnecting } = getState(); - setIsAutoConnecting(val); - } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 41c782a..ca19ec6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,22 +1,11 @@ // import { Client, createClient } from './client'; import Client from "./client/client"; -import { useStore } from "./store/rootStore"; +import { useStore, getState, setState } from "./store/rootStore"; -import { - type ClientConfig, - type ConnectedData, - BaseConnector, - TProvider, -} from "./types"; +import { BaseConnector } from "./types/BaseConnector"; -import setLastUsedConnector from "./utils/util"; +import setLastUsedConnector from "./utils"; -export { - Client, - type ClientConfig, - type ConnectedData, - type TProvider, - BaseConnector, - setLastUsedConnector, - useStore, -}; +export { Client, BaseConnector, setLastUsedConnector }; + +export { useStore, getState, setState }; diff --git a/packages/core/src/store/createAccountSlice.ts b/packages/core/src/store/createAccountSlice.ts index 5888f6a..f8136b2 100644 --- a/packages/core/src/store/createAccountSlice.ts +++ b/packages/core/src/store/createAccountSlice.ts @@ -1,5 +1,5 @@ -import { StateCreator } from 'zustand'; -import { IAccountState } from './storeTypes'; +import { StateCreator } from "zustand"; +import { IAccountState } from "./storeTypes"; const createAccountSlice: StateCreator< IAccountState, @@ -8,10 +8,14 @@ const createAccountSlice: StateCreator< IAccountState > = set => ({ address: null, + addresses: [], did: null, setAddress: address => { set(() => ({ address })); }, + setAddresses: addresses => { + set(() => ({ addresses })); + }, setDid: did => { set(() => ({ did })); }, diff --git a/packages/core/src/store/createClientSlice.ts b/packages/core/src/store/createClientSlice.ts index 55ea0b8..52a628f 100644 --- a/packages/core/src/store/createClientSlice.ts +++ b/packages/core/src/store/createClientSlice.ts @@ -7,17 +7,11 @@ const createClientSlice: StateCreator< [], IClientState > = set => ({ - activeChain: null, - autoConnect: false, + ecosystem: null, connectors: [], activeConnector: null, - lastUsedConnector: null, - isAutoConnecting: true, - setActiveChain: activeChain => { - set(() => ({ activeChain })); - }, - setAutoConnect: autoConnect => { - set(() => ({ autoConnect })); + setEcosystem: ecosystem => { + set(() => ({ ecosystem })); }, setConnectors: connectors => { set(() => ({ connectors })); @@ -25,12 +19,6 @@ const createClientSlice: StateCreator< setActiveConnector: activeConnector => { set(() => ({ activeConnector })); }, - setLastUsedConnector: lastUsedConnector => { - set(() => ({ lastUsedConnector })); - }, - setIsAutoConnecting: val => { - set(() => ({ isAutoConnecting: val })); - }, }); export default createClientSlice; diff --git a/packages/core/src/store/createWalletSlice.ts b/packages/core/src/store/createWalletSlice.ts index 6efc36f..ed8c8f5 100644 --- a/packages/core/src/store/createWalletSlice.ts +++ b/packages/core/src/store/createWalletSlice.ts @@ -1,5 +1,5 @@ -import { StateCreator } from 'zustand'; -import { IWalletState } from './storeTypes'; +import { StateCreator } from "zustand"; +import { IWalletState } from "./storeTypes"; const createWalletSlice: StateCreator< IWalletState, @@ -8,7 +8,7 @@ const createWalletSlice: StateCreator< IWalletState > = set => ({ isConnected: false, - chainId: null, + chainId: "default", setIsConnected: isConnected => { set(() => ({ isConnected })); }, diff --git a/packages/core/src/store/rootStore.ts b/packages/core/src/store/rootStore.ts index 268ac87..da0cd98 100644 --- a/packages/core/src/store/rootStore.ts +++ b/packages/core/src/store/rootStore.ts @@ -1,8 +1,8 @@ -import create from 'zustand'; -import createAccountSlice from './createAccountSlice'; -import createClientSlice from './createClientSlice'; -import createWalletSlice from './createWalletSlice'; -import { IState } from './storeTypes'; +import create from "zustand"; +import createAccountSlice from "./createAccountSlice"; +import createClientSlice from "./createClientSlice"; +import createWalletSlice from "./createWalletSlice"; +import { IState } from "./storeTypes"; export const useStore = create()((...a) => ({ ...createAccountSlice(...a), @@ -10,6 +10,6 @@ export const useStore = create()((...a) => ({ ...createClientSlice(...a), })); -const { getState } = useStore; +export const { getState, setState } = useStore; -export default getState; +// export default getState; diff --git a/packages/core/src/store/storeTypes.ts b/packages/core/src/store/storeTypes.ts index 81a5b93..97a1523 100644 --- a/packages/core/src/store/storeTypes.ts +++ b/packages/core/src/store/storeTypes.ts @@ -1,34 +1,30 @@ import { BaseConnector } from "../types"; +export type TEcosystem = "ethereum" | "solana" | "cosmos" | "tezos"; + export interface IAccountState { address: string | null; + addresses: string[]; did: string | null; setAddress: (address: string | null) => void; + setAddresses: (addresses: string[]) => void; setDid: (did: string | null) => void; } export interface IWalletState { isConnected: boolean; - chainId: string | null; + chainId: "default" | string; setIsConnected: (val: boolean) => void; - setChainId: (id: string | null) => void; + setChainId: (id: "default" | string) => void; } export interface IClientState { - activeChain: "ethereum" | "solana" | "cosmos" | "tezos" | null; - autoConnect: boolean; + ecosystem: TEcosystem | null; connectors: BaseConnector[]; activeConnector: BaseConnector | null; - lastUsedConnector: BaseConnector | null; - isAutoConnecting: boolean; - setActiveChain: ( - val: "ethereum" | "solana" | "cosmos" | "tezos" | null - ) => void; - setAutoConnect: (val: boolean) => void; + setEcosystem: (val: TEcosystem) => void; setConnectors: (connectors: BaseConnector[]) => void; setActiveConnector: (connector: BaseConnector | null) => void; - setLastUsedConnector: (connector: BaseConnector | null) => void; - setIsAutoConnecting: (val: boolean) => void; } export type IState = IAccountState & IWalletState & IClientState; diff --git a/packages/core/src/types/BaseConnector.ts b/packages/core/src/types/BaseConnector.ts new file mode 100644 index 0000000..fd6f588 --- /dev/null +++ b/packages/core/src/types/BaseConnector.ts @@ -0,0 +1,49 @@ +import { AddChainParameter } from "./methodTypes"; +import { Wallet01Store } from "../client/store"; +import { TEcosystem } from "../store/storeTypes"; +import { EnhancedEventEmitter, Events } from "../utils/EnhancedEventEmitter"; +import { + ChainSwitchResponse, + ConnectionResponse, + DisconnectionResponse, + MessageSignedResponse, +} from "./methodTypes"; +import { ConnectorEvents } from "./events"; + +export abstract class BaseConnector< + TProvider extends {} = {}, + TWalletName extends string = string, + TEvents extends Events = ConnectorEvents, +> extends EnhancedEventEmitter { + abstract provider: TProvider; + readonly name: TWalletName; + readonly ecosystem: TEcosystem; + readonly store: Wallet01Store = Wallet01Store.init(); + + constructor(name: TWalletName, ecosystem: TEcosystem) { + super(); + this.name = name; + this.ecosystem = ecosystem; + } + + abstract init(): BaseConnector; + + abstract connect({ + chainId, + }?: { + chainId?: string | undefined; + }): Promise; + + abstract disconnect(): Promise; + + abstract getAccount(): Promise; + + getChainId?(): Promise; + + abstract getProvider(): Promise; + + abstract signMessage(message: string): Promise; + + switchChain?(chainId: string): Promise; + switchChain?(options: AddChainParameter): Promise; +} diff --git a/packages/core/src/types/TProvider.ts b/packages/core/src/types/TProvider.ts deleted file mode 100644 index b396194..0000000 --- a/packages/core/src/types/TProvider.ts +++ /dev/null @@ -1 +0,0 @@ -export type TProvider = any; diff --git a/packages/core/src/types/baseConnector.ts b/packages/core/src/types/baseConnector.ts deleted file mode 100644 index 7ff1bc8..0000000 --- a/packages/core/src/types/baseConnector.ts +++ /dev/null @@ -1,41 +0,0 @@ -export abstract class BaseConnector { - chain: string; - readonly name: string; - readonly activeChain: "ethereum" | "solana" | "cosmos" | "tezos"; - abstract provider?: Provider; - - constructor( - chain: string, - name: string, - activeChain: "ethereum" | "solana" | "cosmos" | "tezos" - ) { - this.chain = chain; - this.name = name; - this.activeChain = activeChain; - } - - abstract connect({ - chainId, - }: { - chainId?: string | undefined; - }): Promise; - - // DISCUSSION: We might wanna have the disconnect method only in the client as there is no specific function in wallets - abstract disconnect(): Promise; - - abstract getAccount(): Promise; - - getChainId?(): Promise; - - abstract getProvider(): Promise; - - abstract resolveDid(address: string): Promise; - - abstract signMessage(message: string): Promise; - - switchChain?(chainId: string): Promise; - - protected abstract onAccountsChanged(): void; - protected abstract onChainChanged(chain: number | string): void; - protected abstract onDisconnect(): void; -} diff --git a/packages/core/src/types/events.ts b/packages/core/src/types/events.ts new file mode 100644 index 0000000..9727980 --- /dev/null +++ b/packages/core/src/types/events.ts @@ -0,0 +1,27 @@ +import { TEcosystem } from "../store/storeTypes"; +import { BaseConnector } from "./BaseConnector"; +import { SignatureHash } from "./methodTypes"; + +export type ConnectorEvents = { + connecting: [walletName: string, ecosystem: TEcosystem]; + connected: [ + address: string, + walletName: string, + ecosystem: TEcosystem, + activeConnector: BaseConnector, + ]; + disconnected: [walletName: string, ecosystem: TEcosystem]; + chainChanged: [chainId: string, activeConnector: BaseConnector]; + accountChanged: [address: string, activeConnector: BaseConnector]; + messageSigned: [signature: SignatureHash, activeConnector: BaseConnector]; + error: [error: Error]; + switchingChain: [ + fromChainId: string | "default", + toChainId: string | "default", + activeConnector: BaseConnector, + ]; +}; + +export type ClientEvents = { + isAutoConnecting: [ecosystem: TEcosystem, lastUsedConnector: BaseConnector]; +}; diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 4842926..409a945 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -1,15 +1,3 @@ -import { BaseConnector } from './baseConnector'; -import { TProvider } from './TProvider'; +import { BaseConnector } from "./BaseConnector"; -type ClientConfig = { - chainId: string; - connector: BaseConnector; -}; - -type ConnectedData = { - account: string; - chainId: string; - provider: TProvider; -}; - -export { type ClientConfig, type ConnectedData, BaseConnector, type TProvider }; +export { BaseConnector }; diff --git a/packages/core/src/types/methodTypes.ts b/packages/core/src/types/methodTypes.ts new file mode 100644 index 0000000..426c19a --- /dev/null +++ b/packages/core/src/types/methodTypes.ts @@ -0,0 +1,45 @@ +import { TEcosystem } from "../store/storeTypes"; +import { BaseConnector } from "./BaseConnector"; + +export type SignatureHash = string | Uint8Array; + +export type ClientConfig = { + autoConnect?: boolean; + connectors: BaseConnector[]; +}; + +export interface AddChainParameter { + chainId: string; + blockExplorerUrls?: string[]; + chainName?: string; + iconUrls?: string[]; + nativeCurrency?: { + name: string; + symbol: string; + decimals: number; + }; + rpcUrls?: string[]; +} + +export type ConnectionResponse = { + address: string; + walletName: string; + ecosystem: TEcosystem; + activeConnector: BaseConnector; +}; + +export type DisconnectionResponse = { + walletName: string; + ecosystem: TEcosystem; +}; + +export type MessageSignedResponse = { + signature: SignatureHash; + activeConnector: BaseConnector; +}; + +export type ChainSwitchResponse = { + fromChainId: string | "default"; + toChainId: string | "default"; + activeConnector: BaseConnector; +}; diff --git a/packages/core/src/utils/EnhancedEventEmitter.ts b/packages/core/src/utils/EnhancedEventEmitter.ts new file mode 100644 index 0000000..fd96459 --- /dev/null +++ b/packages/core/src/utils/EnhancedEventEmitter.ts @@ -0,0 +1,79 @@ +import { EventEmitter } from "events"; + +export type Events = Record; + +class EnhancedEventEmitter { + private emitter: EventEmitter; + + constructor() { + this.emitter = new EventEmitter(); + this.emitter.setMaxListeners(Infinity); + } + + public on( + eventName: K, + listener: (...args: E[K]) => void + ): this { + this.emitter.on( + eventName as string, + // rome-ignore lint/suspicious/noExplicitAny: need to override the type because default it's any[ and we cannot assign E[K] to any[] + listener as unknown as (...args: any[]) => void + ); + return this; + } + + public off( + eventName: K, + listener: (...args: E[K]) => void + ): this { + this.emitter.off( + eventName as string, + // rome-ignore lint/suspicious/noExplicitAny: + listener as unknown as (...args: any[]) => void + ); + return this; + } + + public listenerCount(eventName: K): number { + return this.emitter.listenerCount(eventName as string); + } + + public listeners( + eventName: K + ): ((...args: E[K]) => void)[] { + return this.emitter.listeners(eventName as string) as (( + ...args: E[K] + ) => void)[]; + } + + public emit(eventName: K, ...args: E[K]): boolean { + return this.emitter.emit(eventName as string, ...args); + } + + public safeEmit(eventName: K, ...args: E[K]): boolean { + return this.emitter.emit(eventName as string, ...args); + } + + public once( + eventName: K, + listener: (...args: E[K]) => void + ): this { + this.emitter.once( + eventName as string, + // rome-ignore lint/suspicious/noExplicitAny: + listener as unknown as (...args: any[]) => void + ); + return this; + } + + protected removeAllListeners(eventName?: K): this { + if (eventName) { + this.emitter.removeAllListeners(eventName as string); + } else { + this.emitter.removeAllListeners(); + } + return this; + } +} + +export { EnhancedEventEmitter }; diff --git a/packages/core/src/utils/errors.ts b/packages/core/src/utils/errors.ts new file mode 100644 index 0000000..1feff28 --- /dev/null +++ b/packages/core/src/utils/errors.ts @@ -0,0 +1,3 @@ +export class AutoConnectionError extends Error { + name = "AutoConnectionError"; +} diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts new file mode 100644 index 0000000..4b03ceb --- /dev/null +++ b/packages/core/src/utils/index.ts @@ -0,0 +1,6 @@ +const setLastUsedConnector = (connectorName: string) => { + if (localStorage.getItem("lastUsedConnector") !== connectorName) + localStorage.setItem("lastUsedConnector", connectorName); +}; + +export default setLastUsedConnector; diff --git a/packages/core/src/utils/util.ts b/packages/core/src/utils/util.ts deleted file mode 100644 index ab12913..0000000 --- a/packages/core/src/utils/util.ts +++ /dev/null @@ -1,6 +0,0 @@ -const setLastUsedConnector = (connectorName: string) => { - if (localStorage.getItem('lastUsedConnector') !== connectorName) - localStorage.setItem('lastUsedConnector', connectorName); -}; - -export default setLastUsedConnector; diff --git a/packages/core/tsup.config.ts b/packages/core/tsup.config.ts index 3fe8046..012413c 100644 --- a/packages/core/tsup.config.ts +++ b/packages/core/tsup.config.ts @@ -10,5 +10,5 @@ export default defineConfig({ entryPoints: ["src/index.ts"], target: "es2020", outDir: "dist", - entry: ["src/**/*.ts"], //include all files under src + entry: ["src/index.ts"], }); From 6827904c3c62dfde6360c559d229aea55f4e2e23 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 5 Oct 2023 12:22:36 +0530 Subject: [PATCH 02/17] feat: banana wallet and coinbase wallet connectors modified --- packages/core/src/index.ts | 2 + packages/core/src/types/BaseConnector.ts | 17 +- packages/core/src/types/events.ts | 3 +- packages/core/src/utils/errors.ts | 54 +++ packages/evm/package.json | 2 +- packages/evm/src/connectors/banana.ts | 160 +++++---- packages/evm/src/connectors/coinbase.ts | 265 ++++++++++----- packages/evm/src/utils/emiter.ts | 12 - packages/evm/src/utils/errors.ts | 41 +++ pnpm-lock.yaml | 411 ++++++----------------- 10 files changed, 499 insertions(+), 468 deletions(-) delete mode 100644 packages/evm/src/utils/emiter.ts create mode 100644 packages/evm/src/utils/errors.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ca19ec6..9c1129a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -9,3 +9,5 @@ import setLastUsedConnector from "./utils"; export { Client, BaseConnector, setLastUsedConnector }; export { useStore, getState, setState }; + +export * from "./utils/errors"; diff --git a/packages/core/src/types/BaseConnector.ts b/packages/core/src/types/BaseConnector.ts index fd6f588..e6a2fa0 100644 --- a/packages/core/src/types/BaseConnector.ts +++ b/packages/core/src/types/BaseConnector.ts @@ -1,7 +1,7 @@ import { AddChainParameter } from "./methodTypes"; import { Wallet01Store } from "../client/store"; import { TEcosystem } from "../store/storeTypes"; -import { EnhancedEventEmitter, Events } from "../utils/EnhancedEventEmitter"; +import { EnhancedEventEmitter } from "../utils/EnhancedEventEmitter"; import { ChainSwitchResponse, ConnectionResponse, @@ -13,7 +13,6 @@ import { ConnectorEvents } from "./events"; export abstract class BaseConnector< TProvider extends {} = {}, TWalletName extends string = string, - TEvents extends Events = ConnectorEvents, > extends EnhancedEventEmitter { abstract provider: TProvider; readonly name: TWalletName; @@ -26,13 +25,9 @@ export abstract class BaseConnector< this.ecosystem = ecosystem; } - abstract init(): BaseConnector; + abstract init(): BaseConnector; - abstract connect({ - chainId, - }?: { - chainId?: string | undefined; - }): Promise; + abstract connect(options?: { chainId: string }): Promise; abstract disconnect(): Promise; @@ -44,6 +39,8 @@ export abstract class BaseConnector< abstract signMessage(message: string): Promise; - switchChain?(chainId: string): Promise; - switchChain?(options: AddChainParameter): Promise; + switchChain?( + chainId: string, + options?: AddChainParameter + ): Promise; } diff --git a/packages/core/src/types/events.ts b/packages/core/src/types/events.ts index 9727980..389dc49 100644 --- a/packages/core/src/types/events.ts +++ b/packages/core/src/types/events.ts @@ -6,13 +6,14 @@ export type ConnectorEvents = { connecting: [walletName: string, ecosystem: TEcosystem]; connected: [ address: string, + chainId: string, walletName: string, ecosystem: TEcosystem, activeConnector: BaseConnector, ]; disconnected: [walletName: string, ecosystem: TEcosystem]; chainChanged: [chainId: string, activeConnector: BaseConnector]; - accountChanged: [address: string, activeConnector: BaseConnector]; + accountsChanged: [address: string[], activeConnector: BaseConnector]; messageSigned: [signature: SignatureHash, activeConnector: BaseConnector]; error: [error: Error]; switchingChain: [ diff --git a/packages/core/src/utils/errors.ts b/packages/core/src/utils/errors.ts index 1feff28..d0c6094 100644 --- a/packages/core/src/utils/errors.ts +++ b/packages/core/src/utils/errors.ts @@ -1,3 +1,57 @@ export class AutoConnectionError extends Error { name = "AutoConnectionError"; } + +export class ProviderNotFoundError extends Error { + name = "ProviderNotFoundError"; + walletName: string; + + constructor({ walletName }: { walletName: string }) { + super(); + this.walletName = walletName; + } +} + +export class WalletConnectionError extends Error { + name = "WalletConnectionError"; + walletName: string; + + constructor({ walletName }: { walletName: string }) { + super(`Error while connecting to ${walletName} wallet.`); + this.walletName = walletName; + } +} + +export class WalletNotConnectedError extends Error { + name = "WalletNotConnectedError"; + walletName: string; + + constructor({ walletName }: { walletName: string }) { + super(`${walletName} wallet is not connected.`); + this.walletName = walletName; + } +} + +export class UnknownError extends Error { + name = "UnknownError"; + + constructor({ + walletName, + atFunction, + }: { + walletName: string; + atFunction: string; + }) { + super( + `There was an unexpected error while using ${walletName} wallet at ${atFunction}(). Check console for more details.` + ); + } +} + +export class UserRejectedRequestError extends Error { + name = "UserRejectedRequestError"; + + constructor() { + super(`User rejected the request.`); + } +} diff --git a/packages/evm/package.json b/packages/evm/package.json index bd307a0..37a00eb 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -12,7 +12,7 @@ "dev": "pnpm build --watch" }, "dependencies": { - "@coinbase/wallet-sdk": "^3.6.3", + "@coinbase/wallet-sdk": "^3.7.2", "@ethersproject/providers": "^5.7.2", "@metamask/detect-provider": "^2.0.0", "@rize-labs/banana-wallet-sdk": "^0.1.18", diff --git a/packages/evm/src/connectors/banana.ts b/packages/evm/src/connectors/banana.ts index 4b62336..baed94b 100644 --- a/packages/evm/src/connectors/banana.ts +++ b/packages/evm/src/connectors/banana.ts @@ -1,94 +1,102 @@ -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + BaseConnector, + ProviderNotFoundError, + WalletConnectionError, + WalletNotConnectedError, +} from "@wallet01/core"; import { Banana4337Provider, Banana, Wallet, + Chains, } from "@rize-labs/banana-wallet-sdk"; import { isBananSupported, getBananaSupportedChain } from "../utils/helpers"; +import { + MessageSignError, + UnsupportedChainError, + WalletCreationError, +} from "../utils/errors"; export class BananaConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: Banana4337Provider; - BananaInstance: Banana; - wallet!: Wallet; - address!: string; - connected!: boolean; - - constructor(chain: string = "80001") { - super(chain, "banana", "ethereum"); - if (isBananSupported(chain)) { - const bananaChain = getBananaSupportedChain(chain); - this.BananaInstance = new Banana(bananaChain); - } else { - throw new Error("Chainid passed not supported"); + private BananaInstance!: Banana; + private wallet!: Wallet; + + constructor() { + super("banana", "ethereum"); + } + + init() { + if (!BananaConnector.#instance) { + BananaConnector.#instance = + new BananaConnector() as BaseConnector; } + return BananaConnector.#instance; } - async getProvider(): Promise { - try { - if (!this.provider) { - if (this.wallet) { - const provider = this.wallet.getProvider(); - this.provider = provider; - return this.provider; - } - await this.connect(); - //@ts-ignore - this.provider = this.wallet.getProvider(); - return this.provider; - } + static getInstance() { + return this.#instance; + } - return this.provider; - } catch (error) { - console.error(error); - throw error; + async getProvider(): Promise { + if (!this.provider) { + throw new ProviderNotFoundError({ walletName: this.name }); } + + return this.provider; } - async connect(): Promise { + async connect() { + this.BananaInstance = new Banana(Chains.mumbai); const walletName = this.BananaInstance.getWalletName(); - let provider; if (walletName) { this.wallet = await this.BananaInstance.connectWallet(walletName); if (!this.wallet) { - throw new Error("Wallet connection failed"); + throw new WalletConnectionError({ walletName: this.name }); } - provider = this.wallet.getProvider(); + this.provider = this.wallet.getProvider(); } else { // @ts-ignore-next-line this.wallet = await this.BananaInstance.createWallet(); if (!this.wallet) { - throw new Error("Wallet creation failed"); + throw new WalletCreationError({ walletName: this.name }); } - provider = this.wallet.getProvider(); + this.provider = this.wallet.getProvider(); } - setLastUsedConnector(this.name); - provider.on("accountsChanged", this.onAccountsChanged.bind(this)); - provider.on("disconnect", this.onDisconnect.bind(this)); - provider.on("chainChanged", this.onChainChanged.bind(this)); - - this.address = await this.wallet.getAddress(); - this.connected = true; + this.provider.on("accountsChanged", this.onAccountsChanged.bind(this)); + this.provider.on("disconnect", this.onDisconnect.bind(this)); + this.provider.on("chainChanged", this.onChainChanged.bind(this)); + + const address = await this.wallet.getAddress(); + const chainId = await this.getChainId(); + + this.emit( + "connected", + address, + chainId, + this.name, + this.ecosystem, + BananaConnector.getInstance() + ); + + return { + address, + walletName: this.name, + ecosystem: this.ecosystem, + activeConnector: BananaConnector.getInstance(), + }; } - async resolveDid(address: string): Promise { - try { - if (!this.provider) throw new Error("Wallet not connected"); - if ((await this.getChainId()) !== "1") return null; - const name = this.provider.lookupAddress(address); - return name; - } catch (error) { - console.error(error); - throw error; - } - } - - async switchChain(chainId: string): Promise { + async switchChain(chainId: string) { + const oldChainId = await this.getChainId(); const isNewChainSupported = isBananSupported(chainId); if (!isNewChainSupported) - throw new Error(`Unsupported chainId: ${chainId}`); + throw new UnsupportedChainError({ chainId: chainId }); const bananaChain = getBananaSupportedChain(chainId); @@ -96,19 +104,30 @@ export class BananaConnector extends BaseConnector { this.BananaInstance = BananaInstance; // connect to same wallet with new configs - await this.connect(); + const connection = await this.connect(); + + this.emit("chainChanged", chainId, BananaConnector.getInstance()); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: connection.activeConnector, + }; } - async signMessage(message: string): Promise { + async signMessage(message: string) { try { if (!this.provider) throw new Error("Wallet not Connected!"); const signer = this.wallet.getSigner(); const hash = (await signer.signBananaMessage(message)).signature; - return hash; + return { + signature: hash, + activeConnector: BananaConnector.getInstance(), + }; } catch (error) { console.error(error); - throw error; + throw new MessageSignError({ walletName: this.name }); } } @@ -116,8 +135,9 @@ export class BananaConnector extends BaseConnector { async getAccount(): Promise { if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const result = [this.address]; + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); + const result = [await this.wallet.getAddress()]; return result; } catch (error) { console.error(error); @@ -126,14 +146,18 @@ export class BananaConnector extends BaseConnector { } async disconnect() { - this.connected = false; + this.onDisconnect(); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } async getChainId(): Promise { if (this.provider) { - const id = this.provider.chainId; - this.chain = id.toString(); - return this.chain; + const id = this.provider.chainId.toString(); + this.store.setChainId(id); + return id; } return ""; } @@ -148,6 +172,6 @@ export class BananaConnector extends BaseConnector { } protected onDisconnect(): void { - this.connected = false; + this.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index 3bbb595..3d722b3 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -1,23 +1,46 @@ -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, + UserRejectedRequestError, +} from "@wallet01/core"; import { CoinbaseWalletProvider } from "@coinbase/wallet-sdk"; import { CoinbaseWalletSDK } from "@coinbase/wallet-sdk"; -import { ExternalProvider, Web3Provider } from "@ethersproject/providers"; -import { hexValue } from "ethers/lib/utils.js"; -import { chainData } from "../utils/chains"; - +import { hexValue, hexlify, toUtf8Bytes } from "ethers/lib/utils.js"; +import { CoinbaseWalletSDKOptions } from "@coinbase/wallet-sdk/dist/CoinbaseWalletSDK"; +import { UnrecognisedChainError } from "../utils/errors"; +import { AddChainParameter } from "@wallet01/core/dist/types/methodTypes"; export class CoinbaseConnector extends BaseConnector { - provider?: CoinbaseWalletProvider; + static #instance: BaseConnector; + provider!: CoinbaseWalletProvider; + static options: CoinbaseWalletSDKOptions; + + constructor(options: CoinbaseWalletSDKOptions) { + super("coinbase", "ethereum"); + CoinbaseConnector.options = options; + } + + init() { + if (!CoinbaseConnector.#instance) { + CoinbaseConnector.#instance = new CoinbaseConnector( + CoinbaseConnector.options + ) as BaseConnector; + } + return CoinbaseConnector.#instance; + } - constructor(chain: string = "1") { - super(chain, "coinbase", "ethereum"); + static getInstance(options: CoinbaseWalletSDKOptions) { + this.options = options; + return CoinbaseConnector.#instance; } async getProvider(): Promise { try { - const _provider = new CoinbaseWalletSDK({ - appName: "Wallet01", - }).makeWeb3Provider(); - this.provider = _provider; + if (this.provider) return this.provider; + const provider = new CoinbaseWalletSDK( + CoinbaseConnector.options + ).makeWeb3Provider(); + this.provider = provider; return this.provider; } catch (error) { console.error(error); @@ -28,115 +51,205 @@ export class CoinbaseConnector extends BaseConnector { async getAccount(): Promise { if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const result: string[] = await this.provider.send( - "eth_requestAccounts", - [] - ); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const result = (await this.provider.request({ + method: "eth_requestAccounts", + })) as string[]; + return result; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } - async getChainId(): Promise { - if (this.provider) { - const id = this.provider.chainId; - this.chain = id; - return id; + async getChainId() { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const id = (await this.provider.request({ + method: "eth_chainId", + })) as string; + + const chainId = parseInt(id, 16).toString(); + return chainId; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } - return ""; } - async switchChain(chainId: string): Promise { - if (!this.provider) throw new Error("Wallet Not Connected"); - const id = hexValue(Number(chainId)); - + async switchChain(chainId: string, options?: AddChainParameter | undefined) { + if (!this.provider) await this.getProvider(); try { - await this.provider.request({ + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const oldChainId = await this.getChainId(); + const hexChainId = hexValue(Number(chainId)); + const params = [{ chainId: hexChainId }]; + + const response = await this.provider.request({ method: "wallet_switchEthereumChain", - params: [{ chainId: id }], + params, }); - this.chain = chainId; - } catch (error) { - console.error(error); - if (chainData[chainId]) { - this.provider.request({ + + if ((response as any).code === 4902) { + if (!options) { + throw new UnrecognisedChainError({ walletName: this.name, chainId }); + } + + await this.provider.request({ method: "wallet_addEthereumChain", - params: [{ data: chainData[chainId] }], + params: [options], }); - this.switchChain(chainId); } - throw error; + + this.emit("switchingChain", oldChainId, chainId, this); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: CoinbaseConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "switchChain", + }); } } - async connect({ chainId }: { chainId?: string | undefined }): Promise { + async connect(options?: { chainId: string }) { if (!this.provider) await this.getProvider(); try { - await this.provider?.enable(); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const response = await this.provider.request({ + method: "eth_requestAccounts", + }); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + this.provider.on("accountsChanged", this.onAccountsChanged); + this.provider.on("disconnect", this.onDisconnect); + this.provider.on("chainChanged", this.onChainChanged); - let currentId = await this.getChainId(); - if (chainId && currentId !== chainId) { - await this.switchChain(chainId); + const currentId = await this.getChainId(); + if (options?.chainId && currentId !== options.chainId) { + await this.switchChain(options.chainId); } - setLastUsedConnector(this.name); + const address = await this.getAccount(); + + this.emit( + "connected", + address[0]!, + currentId, + this.name, + this.ecosystem, + CoinbaseConnector.#instance + ); + + return { + address: address[0]!, + walletName: this.name, + ecosystem: this.ecosystem, + activeConnector: CoinbaseConnector.#instance, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "connect", + }); } } - async disconnect(): Promise { - if (!this.provider) throw new Error("Wallet already disconnected"); - await this.provider.disconnect(); - this.provider = undefined; - } - - async resolveDid(address: string): Promise { + async disconnect() { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet not connected"); - if ((await this.getChainId()) !== "1") return null; - - const _provider = new Web3Provider( - this.provider as unknown as ExternalProvider - ); - const name = _provider.lookupAddress(address); - return name; + await this.provider.disconnect(); + this.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); } } - async signMessage(message: string): Promise { + async signMessage(message: string) { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet not Connected!"); - const _address = await this.getAccount(); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const address = await this.getAccount(); + + const hexMessage = hexlify(toUtf8Bytes(message)); - const signer = new Web3Provider( - this.provider as unknown as ExternalProvider - ).getSigner(_address[0]); + const response = await this.provider.request({ + method: "personal_sign", + params: [hexMessage, address[0]], + }); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } - const hash = await signer.signMessage(message); - return hash; + this.emit( + "messageSigned", + response as string, + CoinbaseConnector.#instance + ); + + return { + signature: response as string, + activeConnector: CoinbaseConnector.getInstance( + CoinbaseConnector.options + ), + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); } } - protected onAccountsChanged(): void { - console.log("Account Changed"); + protected onAccountsChanged(accounts: string[]): void { + this.emit("accountsChanged", accounts, CoinbaseConnector.#instance); } - protected onChainChanged(_chain: string): void { - console.log("Chain Changed"); + protected onChainChanged(hexChainId: string): void { + const chainId = parseInt(hexChainId, 16).toString(); + this.emit("chainChanged", chainId, CoinbaseConnector.#instance); } - protected onDisconnect(): void { - console.log("Wallet disconnected"); + protected onDisconnect(error: any): void { + console.error({ + error, + }); + this.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/utils/emiter.ts b/packages/evm/src/utils/emiter.ts deleted file mode 100644 index 17c4b4b..0000000 --- a/packages/evm/src/utils/emiter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import EventEmitter from 'eventemitter3'; - -const eventEmitter = new EventEmitter(); -const emitter = { - on: (event: string, fn: (args: any) => void) => eventEmitter.on(event, fn), - once: (event: string, fn: () => void) => eventEmitter.once(event, fn), - off: (event: string, fn: () => void) => eventEmitter.off(event, fn), - emit: (event: string, payload?: unknown) => eventEmitter.emit(event, payload), -}; - -Object.freeze(emitter); -export default emitter; diff --git a/packages/evm/src/utils/errors.ts b/packages/evm/src/utils/errors.ts new file mode 100644 index 0000000..e8c0271 --- /dev/null +++ b/packages/evm/src/utils/errors.ts @@ -0,0 +1,41 @@ +export class UnsupportedChainError extends Error { + name = "UnsupportedChainError"; + chainId: string; + + constructor({ chainId }: { chainId: string }) { + super(`ChainId: ${chainId} is not supported`); + this.chainId = chainId; + } +} + +export class WalletCreationError extends Error { + name = "WalletCreationError"; + + constructor({ walletName }: { walletName: string }) { + super(`Error while creating ${walletName} wallet.`); + } +} + +export class MessageSignError extends Error { + name = "MessageSignError"; + + constructor({ walletName }: { walletName: string }) { + super(`Error while signing message with ${walletName} wallet.`); + } +} + +export class UnrecognisedChainError extends Error { + name = "UnrecognisedChainError"; + + constructor({ + walletName, + chainId, + }: { + walletName: string; + chainId: string; + }) { + super( + `Unrecognised chainId ${chainId} provided. Please provide options to add chain to ${walletName} wallet.` + ); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc6d509..01d4be8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: false @@ -16,10 +16,10 @@ importers: version: link:configs/eslint prettier: specifier: latest - version: 3.0.0 + version: 3.0.3 turbo: specifier: latest - version: 1.10.6 + version: 1.10.14 configs/eslint: dependencies: @@ -31,7 +31,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 0.0.10(eslint@7.32.0) + version: 1.10.14(eslint@7.32.0) devDependencies: typescript: specifier: ^4.7.4 @@ -211,8 +211,8 @@ importers: packages/evm: dependencies: '@coinbase/wallet-sdk': - specifier: ^3.6.3 - version: 3.6.3 + specifier: ^3.7.2 + version: 3.7.2 '@ethersproject/providers': specifier: ^5.7.2 version: 5.7.2 @@ -486,6 +486,7 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 + dev: true /@babel/code-frame@7.12.11: resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} @@ -498,10 +499,12 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 + dev: true /@babel/compat-data@7.20.1: resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==} engines: {node: '>=6.9.0'} + dev: true /@babel/core@7.20.2: resolution: {integrity: sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==} @@ -524,6 +527,7 @@ packages: semver: 6.3.0 transitivePeerDependencies: - supports-color + dev: true /@babel/generator@7.20.4: resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} @@ -532,6 +536,7 @@ packages: '@babel/types': 7.20.2 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 + dev: true /@babel/helper-annotate-as-pure@7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} @@ -551,25 +556,12 @@ packages: '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 semver: 6.3.0 - - /@babel/helper-define-polyfill-provider@0.3.3: - resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} - peerDependencies: - '@babel/core': ^7.4.0-0 - dependencies: - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.2) - '@babel/helper-plugin-utils': 7.20.2 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: false + dev: true /@babel/helper-environment-visitor@7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-function-name@7.19.0: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} @@ -577,18 +569,21 @@ packages: dependencies: '@babel/template': 7.18.10 '@babel/types': 7.20.2 + dev: true /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.2 + dev: true /@babel/helper-module-imports@7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.2 + dev: true /@babel/helper-module-transforms@7.20.2: resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} @@ -604,26 +599,31 @@ packages: '@babel/types': 7.20.2 transitivePeerDependencies: - supports-color + dev: true /@babel/helper-plugin-utils@7.20.2: resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-simple-access@7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.2 + dev: true /@babel/helper-split-export-declaration@7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.2 + dev: true /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} @@ -632,6 +632,7 @@ packages: /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} + dev: true /@babel/helpers@7.20.1: resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} @@ -642,6 +643,7 @@ packages: '@babel/types': 7.20.2 transitivePeerDependencies: - supports-color + dev: true /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -656,6 +658,7 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@babel/types': 7.20.2 + dev: true /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.20.2): resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} @@ -711,22 +714,6 @@ packages: '@babel/types': 7.20.2 dev: true - /@babel/plugin-transform-runtime@7.19.6: - resolution: {integrity: sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - babel-plugin-polyfill-corejs2: 0.3.3 - babel-plugin-polyfill-corejs3: 0.6.0 - babel-plugin-polyfill-regenerator: 0.4.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/runtime-corejs3@7.20.1: resolution: {integrity: sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==} engines: {node: '>=6.9.0'} @@ -748,6 +735,7 @@ packages: '@babel/code-frame': 7.18.6 '@babel/parser': 7.20.3 '@babel/types': 7.20.2 + dev: true /@babel/traverse@7.20.1: resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} @@ -765,6 +753,7 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color + dev: true /@babel/types@7.20.2: resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==} @@ -773,6 +762,7 @@ packages: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + dev: true /@bonfida/name-offers@0.0.1: resolution: {integrity: sha512-R0GJ/+R5OXfm4KfiKEjHx88QnQxw+kzDA8O4pHouev1voPJueOzzo5x+YLowMpk3/2maqEwkNPWiWIlSExjdug==} @@ -995,8 +985,8 @@ packages: prettier: 2.8.8 dev: true - /@coinbase/wallet-sdk@3.6.3: - resolution: {integrity: sha512-XUR4poOJE+dKzwBTdlM693CdLFitr046oZOVY3iDnbFcRrrQswhbDji7q4CmUcD4HxbfViX7PFoIwl79YQcukg==} + /@coinbase/wallet-sdk@3.7.2: + resolution: {integrity: sha512-lIGvXMsgpsQWci/XOMQIJ2nIZ8JUy/L+bvC0wkRaYarr0YylwpXrJ2gRM3hCXPS477pkyO7N/kSiAoRgEXUdJQ==} engines: {node: '>= 10.0.0'} dependencies: '@metamask/safe-event-emitter': 2.0.0 @@ -1005,8 +995,8 @@ packages: bn.js: 5.2.1 buffer: 6.0.3 clsx: 1.2.1 - eth-block-tracker: 4.4.3 - eth-json-rpc-filters: 4.2.2 + eth-block-tracker: 6.1.0 + eth-json-rpc-filters: 5.1.0 eth-rpc-errors: 4.0.2 json-rpc-engine: 6.1.0 keccak: 3.0.3 @@ -1017,7 +1007,6 @@ packages: stream-browserify: 3.0.0 util: 0.12.5 transitivePeerDependencies: - - '@babel/core' - bufferutil - encoding - supports-color @@ -1462,6 +1451,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 + dev: true /@jridgewell/gen-mapping@0.3.2: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} @@ -1470,23 +1460,28 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 '@jridgewell/trace-mapping': 0.3.17 + dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} + dev: true /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} + dev: true /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true /@jridgewell/trace-mapping@0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + dev: true /@keplr-wallet/types@0.11.17: resolution: {integrity: sha512-ks3+L8SR4Wnn/kqafpJB2g/wzgNVoW3Y48Qb8vddnWmgub/ib1g1Xs3RB7lRzvrgWsuj2xmNCK9BFLcdisW6+g==} @@ -1537,6 +1532,18 @@ packages: resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} dev: false + /@metamask/utils@3.6.0: + resolution: {integrity: sha512-9cIRrfkWvHblSiNDVXsjivqa9Ak0RYo/1H6tqTqTbAx+oBK2Sva0lWDHxGchOqA7bySGUJKAWSNJvH6gdHZ0gQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@types/debug': 4.1.7 + debug: 4.3.4 + semver: 7.3.8 + superstruct: 1.0.3 + transitivePeerDependencies: + - supports-color + dev: false + /@motionone/animation@10.15.1: resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} dependencies: @@ -2290,12 +2297,6 @@ packages: nanoid: 3.3.4 dev: false - /@types/bn.js@4.11.6: - resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} - dependencies: - '@types/node': 18.11.18 - dev: false - /@types/bs58check@2.1.0: resolution: {integrity: sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==} dependencies: @@ -2375,12 +2376,6 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true - /@types/pbkdf2@3.1.0: - resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} - dependencies: - '@types/node': 18.11.18 - dev: false - /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true @@ -2409,12 +2404,6 @@ packages: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} dev: true - /@types/secp256k1@4.0.3: - resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} - dependencies: - '@types/node': 18.11.18 - dev: false - /@types/semver@6.2.3: resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} dev: true @@ -3204,39 +3193,6 @@ packages: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} dev: true - /babel-plugin-polyfill-corejs2@0.3.3: - resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/helper-define-polyfill-provider': 0.3.3 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-corejs3@0.6.0: - resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/helper-define-polyfill-provider': 0.3.3 - core-js-compat: 3.27.1 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-regenerator@0.4.1: - resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/helper-define-polyfill-provider': 0.3.3 - transitivePeerDependencies: - - supports-color - dev: false - /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -3405,6 +3361,7 @@ packages: electron-to-chromium: 1.4.284 node-releases: 2.0.6 update-browserslist-db: 1.0.10(browserslist@4.21.4) + dev: true /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} @@ -3420,11 +3377,6 @@ packages: safe-buffer: 5.2.1 dev: false - /btoa@1.2.1: - resolution: {integrity: sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==} - engines: {node: '>= 0.4.0'} - dev: false - /buffer-layout@1.2.2: resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} engines: {node: '>=4.5'} @@ -3584,11 +3536,6 @@ packages: engines: {node: '>=0.8'} dev: true - /clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - dev: false - /clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -3632,12 +3579,7 @@ packages: /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - - /core-js-compat@3.27.1: - resolution: {integrity: sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==} - dependencies: - browserslist: 4.21.4 - dev: false + dev: true /core-js-pure@3.26.1: resolution: {integrity: sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==} @@ -3910,6 +3852,11 @@ packages: engines: {node: '>=10'} dev: false + /dotenv@16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} + engines: {node: '>=12'} + dev: false + /duplexify@4.1.2: resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} dependencies: @@ -3921,6 +3868,7 @@ packages: /electron-to-chromium@1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + dev: true /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} @@ -4230,6 +4178,7 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -4273,13 +4222,13 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@0.0.10(eslint@7.32.0): - resolution: {integrity: sha512-o4ULFZYM1OihSd63eDGEuy9rt6tW4ma6xnW9grnr44BoJwKaGQko2aka9kfqQs0vtmwD1++Os3ThPHETmzkFzA==} + /eslint-config-turbo@1.10.14(eslint@7.32.0): + resolution: {integrity: sha512-ZeB+IcuFXy1OICkLuAplVa0euoYbhK+bMEQd0nH9+Lns18lgZRm33mVz/iSoH9VdUzl/1ZmFmoK+RpZc+8R80A==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 0.0.10(eslint@7.32.0) + eslint-plugin-turbo: 1.10.14(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -4425,11 +4374,12 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@0.0.10(eslint@7.32.0): - resolution: {integrity: sha512-T7QRwF4rjBQCJD9AHLHn9ShtHCHNkfIZW5Oio92WtQYhoU5jZCU3ynU+ONFXLuvoUx4dJ19WergIyHL+DwL2+g==} + /eslint-plugin-turbo@1.10.14(eslint@7.32.0): + resolution: {integrity: sha512-sBdBDnYr9AjT1g4lR3PBkZDonTrMnR4TvuGv5W0OiF7z9az1rI68yj2UHJZvjkwwcGu5mazWA1AfB0oaagpmfg==} peerDependencies: eslint: '>6.6.0' dependencies: + dotenv: 16.0.3 eslint: 7.32.0 dev: false @@ -4622,49 +4572,27 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - /eth-block-tracker@4.4.3: - resolution: {integrity: sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw==} + /eth-block-tracker@6.1.0: + resolution: {integrity: sha512-K9SY8+/xMBi4M5HHTDdxnpEqEEGjbNpzHFqvxyjMZej8InV/B+CkFRKM6W+uvrFJ7m8Zd1E0qUkseU3vdIDFYQ==} + engines: {node: '>=14.0.0'} dependencies: - '@babel/plugin-transform-runtime': 7.19.6 - '@babel/runtime': 7.20.1 - eth-query: 2.1.2 + '@metamask/safe-event-emitter': 2.0.0 + '@metamask/utils': 3.6.0 json-rpc-random-id: 1.0.1 pify: 3.0.0 - safe-event-emitter: 1.0.1 transitivePeerDependencies: - - '@babel/core' - supports-color dev: false - /eth-json-rpc-filters@4.2.2: - resolution: {integrity: sha512-DGtqpLU7bBg63wPMWg1sCpkKCf57dJ+hj/k3zF26anXMzkmtSBDExL8IhUu7LUd34f0Zsce3PYNO2vV2GaTzaw==} + /eth-json-rpc-filters@5.1.0: + resolution: {integrity: sha512-fos+9xmoa1A2Ytsc9eYof17r81BjdJOUcGcgZn4K/tKdCCTb+a8ytEtwlu1op5qsXFDlgGmstTELFrDEc89qEQ==} + engines: {node: '>=14.0.0'} dependencies: '@metamask/safe-event-emitter': 2.0.0 async-mutex: 0.2.6 - eth-json-rpc-middleware: 6.0.0 eth-query: 2.1.2 json-rpc-engine: 6.1.0 pify: 5.0.0 - transitivePeerDependencies: - - encoding - dev: false - - /eth-json-rpc-middleware@6.0.0: - resolution: {integrity: sha512-qqBfLU2Uq1Ou15Wox1s+NX05S9OcAEL4JZ04VZox2NS0U+RtCMjSxzXhLFWekdShUPZ+P8ax3zCO2xcPrp6XJQ==} - dependencies: - btoa: 1.2.1 - clone: 2.1.2 - eth-query: 2.1.2 - eth-rpc-errors: 3.0.0 - eth-sig-util: 1.4.2 - ethereumjs-util: 5.2.1 - json-rpc-engine: 5.4.0 - json-stable-stringify: 1.0.2 - node-fetch: 2.6.7 - pify: 3.0.0 - safe-event-emitter: 1.0.1 - transitivePeerDependencies: - - encoding dev: false /eth-query@2.1.2: @@ -4674,69 +4602,12 @@ packages: xtend: 4.0.2 dev: false - /eth-rpc-errors@3.0.0: - resolution: {integrity: sha512-iPPNHPrLwUlR9xCSYm7HHQjWBasor3+KZfRvwEWxMz3ca0yqnlBeJrnyphkGIXZ4J7AMAaOLmwy4AWhnxOiLxg==} - dependencies: - fast-safe-stringify: 2.1.1 - dev: false - /eth-rpc-errors@4.0.2: resolution: {integrity: sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ==} dependencies: fast-safe-stringify: 2.1.1 dev: false - /eth-sig-util@1.4.2: - resolution: {integrity: sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw==} - dependencies: - ethereumjs-abi: github.com/ethereumjs/ethereumjs-abi/ee3994657fa7a427238e6ba92a84d0b529bbcde0 - ethereumjs-util: 5.2.1 - dev: false - - /ethereum-cryptography@0.1.3: - resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} - dependencies: - '@types/pbkdf2': 3.1.0 - '@types/secp256k1': 4.0.3 - blakejs: 1.2.1 - browserify-aes: 1.2.0 - bs58check: 2.1.2 - create-hash: 1.2.0 - create-hmac: 1.1.7 - hash.js: 1.1.7 - keccak: 3.0.3 - pbkdf2: 3.1.2 - randombytes: 2.1.0 - safe-buffer: 5.2.1 - scrypt-js: 3.0.1 - secp256k1: 4.0.3 - setimmediate: 1.0.5 - dev: false - - /ethereumjs-util@5.2.1: - resolution: {integrity: sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==} - dependencies: - bn.js: 4.12.0 - create-hash: 1.2.0 - elliptic: 6.5.4 - ethereum-cryptography: 0.1.3 - ethjs-util: 0.1.6 - rlp: 2.2.7 - safe-buffer: 5.2.1 - dev: false - - /ethereumjs-util@6.2.1: - resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} - dependencies: - '@types/bn.js': 4.11.6 - bn.js: 4.12.0 - create-hash: 1.2.0 - elliptic: 6.5.4 - ethereum-cryptography: 0.1.3 - ethjs-util: 0.1.6 - rlp: 2.2.7 - dev: false - /ethers@5.7.2: resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} dependencies: @@ -4775,14 +4646,6 @@ packages: - utf-8-validate dev: false - /ethjs-util@0.1.6: - resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} - engines: {node: '>=6.5.0', npm: '>=3'} - dependencies: - is-hex-prefixed: 1.0.0 - strip-hex-prefix: 1.0.0 - dev: false - /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false @@ -5011,6 +4874,7 @@ packages: /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + dev: true /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -5084,6 +4948,7 @@ packages: /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} + dev: true /globals@13.18.0: resolution: {integrity: sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==} @@ -5315,6 +5180,7 @@ packages: resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} dependencies: has: 1.0.3 + dev: true /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -5344,11 +5210,6 @@ packages: dependencies: is-extglob: 2.1.1 - /is-hex-prefixed@1.0.0: - resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} - engines: {node: '>=6.5.0', npm: '>=3'} - dev: false - /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -5542,18 +5403,12 @@ packages: /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} + dev: true /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true - /json-rpc-engine@5.4.0: - resolution: {integrity: sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g==} - dependencies: - eth-rpc-errors: 3.0.0 - safe-event-emitter: 1.0.1 - dev: false - /json-rpc-engine@6.1.0: resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} engines: {node: '>=10.0.0'} @@ -5576,12 +5431,6 @@ packages: /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - /json-stable-stringify@1.0.2: - resolution: {integrity: sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==} - dependencies: - jsonify: 0.0.1 - dev: false - /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: false @@ -5595,6 +5444,7 @@ packages: /json5@2.2.1: resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} engines: {node: '>=6'} + dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -5602,10 +5452,6 @@ packages: graceful-fs: 4.2.10 dev: true - /jsonify@0.0.1: - resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - dev: false - /jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} @@ -5737,10 +5583,6 @@ packages: p-locate: 5.0.0 dev: true - /lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: false - /lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: false @@ -6035,6 +5877,7 @@ packages: /node-releases@2.0.6: resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -6246,6 +6089,7 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -6438,8 +6282,8 @@ packages: hasBin: true dev: true - /prettier@3.0.0: - resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + /prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} engines: {node: '>=14'} hasBin: true dev: true @@ -6747,6 +6591,7 @@ packages: is-core-module: 2.11.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + dev: true /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} @@ -6773,12 +6618,6 @@ packages: inherits: 2.0.4 dev: false - /rlp@2.2.7: - resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} - dependencies: - bn.js: 5.2.1 - dev: false - /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} @@ -6828,12 +6667,6 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false - /safe-event-emitter@1.0.1: - resolution: {integrity: sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==} - dependencies: - events: 3.3.0 - dev: false - /safe-json-utils@1.1.1: resolution: {integrity: sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ==} dev: false @@ -6864,16 +6697,6 @@ packages: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} dev: false - /secp256k1@4.0.3: - resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} - engines: {node: '>=10.0.0'} - requiresBuild: true - dependencies: - elliptic: 6.5.4 - node-addon-api: 2.0.2 - node-gyp-build: 4.5.0 - dev: false - /secretjs@0.17.7: resolution: {integrity: sha512-j39l9+vR2A8067QBqDDejS7LmRLgdkG4uRw2Ar6HMfzDGo26eTh7cIXVlVu/yHBumxtQzKun20epOXwuYHXjQg==} dependencies: @@ -6902,6 +6725,7 @@ packages: /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + dev: true /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} @@ -6917,10 +6741,6 @@ packages: /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: false - /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} dependencies: @@ -7144,13 +6964,6 @@ packages: engines: {node: '>=6'} dev: true - /strip-hex-prefix@1.0.0: - resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} - engines: {node: '>=6.5.0', npm: '>=3'} - dependencies: - is-hex-prefixed: 1.0.0 - dev: false - /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -7195,6 +7008,11 @@ packages: resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} dev: false + /superstruct@1.0.3: + resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} + engines: {node: '>=14.0.0'} + dev: false + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -7210,6 +7028,7 @@ packages: /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + dev: true /table@6.8.1: resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} @@ -7301,6 +7120,7 @@ packages: /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} + dev: true /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -7443,65 +7263,64 @@ packages: yargs: 17.6.2 dev: true - /turbo-darwin-64@1.10.6: - resolution: {integrity: sha512-s2Gc7i9Ud+H9GDcrGJjPIyscJfzDGQ6il4Sl2snfvwngJs4/TaqKuBoX3HNt/7F4NiFRs7ZhlLV1/Yu9zGBRhw==} + /turbo-darwin-64@1.10.14: + resolution: {integrity: sha512-I8RtFk1b9UILAExPdG/XRgGQz95nmXPE7OiGb6ytjtNIR5/UZBS/xVX/7HYpCdmfriKdVwBKhalCoV4oDvAGEg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.6: - resolution: {integrity: sha512-tgl70t5PBLyRcNTdP9N6NjvdvQ5LUk8Z60JGUhBhnc+oCOdA4pltrDJNPyel3tQAXXt1dDpl8pp9vUrbwoVyGg==} + /turbo-darwin-arm64@1.10.14: + resolution: {integrity: sha512-KAdUWryJi/XX7OD0alOuOa0aJ5TLyd4DNIYkHPHYcM6/d7YAovYvxRNwmx9iv6Vx6IkzTnLeTiUB8zy69QkG9Q==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.6: - resolution: {integrity: sha512-h7eyAA3xtAVpamcYJYUwe0xm0LWdbv7/I7QiM09AZ67TTNpyUgqW8giFN3h793BHEQ2Rcnk9FNkpIbjWBbyamg==} + /turbo-linux-64@1.10.14: + resolution: {integrity: sha512-BOBzoREC2u4Vgpap/WDxM6wETVqVMRcM8OZw4hWzqCj2bqbQ6L0wxs1LCLWVrghQf93JBQtIGAdFFLyCSBXjWQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.6: - resolution: {integrity: sha512-8cZhOeLqu3QZ27yLd6bw4FNaB8y5pLdWeRLJeiWHkIb/cptKnRKJFP+keBJzJi8ovaMqdBpabrxiBRN2lhau5Q==} + /turbo-linux-arm64@1.10.14: + resolution: {integrity: sha512-D8T6XxoTdN5D4V5qE2VZG+/lbZX/89BkAEHzXcsSUTRjrwfMepT3d2z8aT6hxv4yu8EDdooZq/2Bn/vjMI32xw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.6: - resolution: {integrity: sha512-qx5jcfCJodN1Mh0KtSVQau7pK8CxDvtif7+joPHI2HbQPAADgdUl0LHfA5tFHh6aWgfvhxbvIXqJd6v7Mqkj9g==} + /turbo-windows-64@1.10.14: + resolution: {integrity: sha512-zKNS3c1w4i6432N0cexZ20r/aIhV62g69opUn82FLVs/zk3Ie0GVkSB6h0rqIvMalCp7enIR87LkPSDGz9K4UA==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.6: - resolution: {integrity: sha512-vTQaRG3/s2XTreOBr6J9HKFtjzusvwGQg0GtuW2+9Z7fizdzP8MuhaDbN6FhKHcWC81PQPD61TBIKTVTsYOEZg==} + /turbo-windows-arm64@1.10.14: + resolution: {integrity: sha512-rkBwrTPTxNSOUF7of8eVvvM+BkfkhA2OvpHM94if8tVsU+khrjglilp8MTVPHlyS9byfemPAmFN90oRIPB05BA==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.6: - resolution: {integrity: sha512-0/wbjw4HvmPP1abVWHTdeFRfCA9cn5oxCPP5bDixagLzvDgGWE3xfdlsyGmq779Ekr9vjtDPgC2Y4JlXEhyryw==} + /turbo@1.10.14: + resolution: {integrity: sha512-hr9wDNYcsee+vLkCDIm8qTtwhJ6+UAMJc3nIY6+PNgUTtXcQgHxCq8BGoL7gbABvNWv76CNbK5qL4Lp9G3ZYRA==} hasBin: true - requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.6 - turbo-darwin-arm64: 1.10.6 - turbo-linux-64: 1.10.6 - turbo-linux-arm64: 1.10.6 - turbo-windows-64: 1.10.6 - turbo-windows-arm64: 1.10.6 + turbo-darwin-64: 1.10.14 + turbo-darwin-arm64: 1.10.14 + turbo-linux-64: 1.10.14 + turbo-linux-arm64: 1.10.14 + turbo-windows-64: 1.10.14 + turbo-windows-arm64: 1.10.14 dev: true /tweetnacl@1.0.3: @@ -7595,6 +7414,7 @@ packages: browserslist: 4.21.4 escalade: 3.1.1 picocolors: 1.0.0 + dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -7933,12 +7753,3 @@ packages: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false - - github.com/ethereumjs/ethereumjs-abi/ee3994657fa7a427238e6ba92a84d0b529bbcde0: - resolution: {tarball: https://codeload.github.com/ethereumjs/ethereumjs-abi/tar.gz/ee3994657fa7a427238e6ba92a84d0b529bbcde0} - name: ethereumjs-abi - version: 0.6.8 - dependencies: - bn.js: 4.12.0 - ethereumjs-util: 6.2.1 - dev: false From 9aebc75cdd7df83c843e9b6fa0e1bc4e08c642fc Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 5 Oct 2023 17:21:20 +0530 Subject: [PATCH 03/17] feat: updating evm packages --- package.json | 3 +- packages/core/src/client/client.ts | 35 ++- packages/core/src/client/store.ts | 15 +- packages/core/src/store/createAccountSlice.ts | 4 - packages/core/src/store/storeTypes.ts | 8 +- packages/core/src/types/BaseConnector.ts | 2 - packages/core/src/types/methodTypes.ts | 1 + packages/evm/package.json | 2 +- packages/evm/src/connectors/banana.ts | 2 +- packages/evm/src/connectors/coinbase.ts | 25 +- packages/evm/src/connectors/injected.ts | 286 +++++++++++------ packages/evm/src/connectors/okxwallet.ts | 285 ++++++++++++----- packages/evm/src/connectors/walletconnect.ts | 289 ++++++++++++------ pnpm-lock.yaml | 57 +++- 14 files changed, 717 insertions(+), 297 deletions(-) diff --git a/package.json b/package.json index efa6027..231d9c6 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,7 @@ "dev": "turbo run dev --parallel", "dev:packages": "turbo run dev --parallel --filter=./packages/*", "lint": "turbo run lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "postinstall": "turbo run build --filter=./packages/*" + "format": "prettier --write \"**/*.{ts,tsx,md}\"" }, "devDependencies": { "@changesets/cli": "^2.25.2", diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index b08fe86..61cb8f2 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -12,8 +12,8 @@ export default class Wallet01Client extends EnhancedEventEmitter< constructor({ autoConnect = false, connectors }: ClientConfig) { super(); - this.store.setConnectors(connectors); + this.registerEventListeners(); if (localStorage.getItem("autoConnect") === null) localStorage.setItem("autoConnect", String(autoConnect)); @@ -43,6 +43,39 @@ export default class Wallet01Client extends EnhancedEventEmitter< return Wallet01Client.#instance; }; + private registerEventListeners() { + // this.on("isAutoConnecting", (ecosystem) => {}) + this.on( + "connected", + (address, chainId, walletName, ecosystem, activeConnector) => { + localStorage.setItem("lastUsedConnector", walletName); + this.store.setActiveConnector(activeConnector); + this.store.setAddress(address); + this.store.setChainId(chainId); + this.store.setEcosystem(ecosystem); + this.store.setIsConnected(true); + } + ); + + this.on("disconnected", () => { + localStorage.removeItem("lastUsedConnector"); + this.store.setActiveConnector(null); + this.store.setAddress(null); + this.store.setChainId(null); + this.store.setEcosystem(null); + this.store.setIsConnected(false); + this.removeAllListeners(); + }); + + this.on("chainChanged", chainId => { + this.store.setChainId(chainId); + }); + + this.on("accountsChanged", addresses => { + this.store.setAddresses(addresses); + }); + } + private async autoConnect() { const lastUsedConnectorName = localStorage.getItem("lastUsedConnector"); diff --git a/packages/core/src/client/store.ts b/packages/core/src/client/store.ts index da87c1c..3489648 100644 --- a/packages/core/src/client/store.ts +++ b/packages/core/src/client/store.ts @@ -33,11 +33,6 @@ export class Wallet01Store { return addresses; } - getDid(): string | null { - const { did } = getState(); - return did; - } - getIsConnected(): boolean { const { isConnected } = getState(); return isConnected; @@ -58,7 +53,7 @@ export class Wallet01Store { return activeConnector; } - setEcosystem(ecosystem: "ethereum" | "solana" | "cosmos" | "tezos") { + setEcosystem(ecosystem: "ethereum" | "solana" | "cosmos" | "tezos" | null) { const { setEcosystem } = getState(); setEcosystem(ecosystem); } @@ -68,9 +63,9 @@ export class Wallet01Store { setAddress(address); } - setDid(did: string | null) { - const { setDid } = getState(); - setDid(did); + setAddresses(addresses: string[]) { + const { setAddresses } = getState(); + setAddresses(addresses); } setIsConnected(val: boolean) { @@ -78,7 +73,7 @@ export class Wallet01Store { setIsConnected(val); } - setChainId(id: string | "default") { + setChainId(id: string | "mainnet" | null) { const { setChainId } = getState(); setChainId(id); } diff --git a/packages/core/src/store/createAccountSlice.ts b/packages/core/src/store/createAccountSlice.ts index f8136b2..7fe68e7 100644 --- a/packages/core/src/store/createAccountSlice.ts +++ b/packages/core/src/store/createAccountSlice.ts @@ -9,16 +9,12 @@ const createAccountSlice: StateCreator< > = set => ({ address: null, addresses: [], - did: null, setAddress: address => { set(() => ({ address })); }, setAddresses: addresses => { set(() => ({ addresses })); }, - setDid: did => { - set(() => ({ did })); - }, }); export default createAccountSlice; diff --git a/packages/core/src/store/storeTypes.ts b/packages/core/src/store/storeTypes.ts index 97a1523..b6708b1 100644 --- a/packages/core/src/store/storeTypes.ts +++ b/packages/core/src/store/storeTypes.ts @@ -5,24 +5,22 @@ export type TEcosystem = "ethereum" | "solana" | "cosmos" | "tezos"; export interface IAccountState { address: string | null; addresses: string[]; - did: string | null; setAddress: (address: string | null) => void; setAddresses: (addresses: string[]) => void; - setDid: (did: string | null) => void; } export interface IWalletState { isConnected: boolean; - chainId: "default" | string; + chainId: "mainnet" | string | null; setIsConnected: (val: boolean) => void; - setChainId: (id: "default" | string) => void; + setChainId: (id: "mainnet" | string | null) => void; } export interface IClientState { ecosystem: TEcosystem | null; connectors: BaseConnector[]; activeConnector: BaseConnector | null; - setEcosystem: (val: TEcosystem) => void; + setEcosystem: (val: TEcosystem | null) => void; setConnectors: (connectors: BaseConnector[]) => void; setActiveConnector: (connector: BaseConnector | null) => void; } diff --git a/packages/core/src/types/BaseConnector.ts b/packages/core/src/types/BaseConnector.ts index e6a2fa0..9f4f61f 100644 --- a/packages/core/src/types/BaseConnector.ts +++ b/packages/core/src/types/BaseConnector.ts @@ -1,5 +1,4 @@ import { AddChainParameter } from "./methodTypes"; -import { Wallet01Store } from "../client/store"; import { TEcosystem } from "../store/storeTypes"; import { EnhancedEventEmitter } from "../utils/EnhancedEventEmitter"; import { @@ -17,7 +16,6 @@ export abstract class BaseConnector< abstract provider: TProvider; readonly name: TWalletName; readonly ecosystem: TEcosystem; - readonly store: Wallet01Store = Wallet01Store.init(); constructor(name: TWalletName, ecosystem: TEcosystem) { super(); diff --git a/packages/core/src/types/methodTypes.ts b/packages/core/src/types/methodTypes.ts index 426c19a..8b06dd5 100644 --- a/packages/core/src/types/methodTypes.ts +++ b/packages/core/src/types/methodTypes.ts @@ -23,6 +23,7 @@ export interface AddChainParameter { export type ConnectionResponse = { address: string; + chainId: string; walletName: string; ecosystem: TEcosystem; activeConnector: BaseConnector; diff --git a/packages/evm/package.json b/packages/evm/package.json index 37a00eb..bb856eb 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -21,7 +21,7 @@ "@walletconnect/modal": "^2.5.2", "@web3modal/core": "^2.2.2", "@web3modal/standalone": "^2.2.2", - "ethers": "^5.7.2", + "ethers": "^6.7.1", "eventemitter3": "^4.0.7" }, "devDependencies": { diff --git a/packages/evm/src/connectors/banana.ts b/packages/evm/src/connectors/banana.ts index baed94b..47239d6 100644 --- a/packages/evm/src/connectors/banana.ts +++ b/packages/evm/src/connectors/banana.ts @@ -87,6 +87,7 @@ export class BananaConnector extends BaseConnector { return { address, walletName: this.name, + chainId, ecosystem: this.ecosystem, activeConnector: BananaConnector.getInstance(), }; @@ -156,7 +157,6 @@ export class BananaConnector extends BaseConnector { async getChainId(): Promise { if (this.provider) { const id = this.provider.chainId.toString(); - this.store.setChainId(id); return id; } return ""; diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index 3d722b3..971b0a9 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -6,14 +6,17 @@ import { } from "@wallet01/core"; import { CoinbaseWalletProvider } from "@coinbase/wallet-sdk"; import { CoinbaseWalletSDK } from "@coinbase/wallet-sdk"; -import { hexValue, hexlify, toUtf8Bytes } from "ethers/lib/utils.js"; +import { hexlify, toUtf8Bytes, toQuantity } from "ethers"; import { CoinbaseWalletSDKOptions } from "@coinbase/wallet-sdk/dist/CoinbaseWalletSDK"; import { UnrecognisedChainError } from "../utils/errors"; -import { AddChainParameter } from "@wallet01/core/dist/types/methodTypes"; +import { + AddChainParameter, + ConnectionResponse, +} from "@wallet01/core/dist/types/methodTypes"; export class CoinbaseConnector extends BaseConnector { static #instance: BaseConnector; - provider!: CoinbaseWalletProvider; static options: CoinbaseWalletSDKOptions; + provider!: CoinbaseWalletProvider; constructor(options: CoinbaseWalletSDKOptions) { super("coinbase", "ethereum"); @@ -96,7 +99,7 @@ export class CoinbaseConnector extends BaseConnector { throw new ProviderNotFoundError({ walletName: this.name }); const oldChainId = await this.getChainId(); - const hexChainId = hexValue(Number(chainId)); + const hexChainId = toQuantity(Number(chainId)); const params = [{ chainId: hexChainId }]; const response = await this.provider.request({ @@ -115,7 +118,12 @@ export class CoinbaseConnector extends BaseConnector { }); } - this.emit("switchingChain", oldChainId, chainId, this); + this.emit( + "switchingChain", + oldChainId, + chainId, + CoinbaseConnector.#instance + ); return { fromChainId: oldChainId, @@ -131,7 +139,7 @@ export class CoinbaseConnector extends BaseConnector { } } - async connect(options?: { chainId: string }) { + async connect(options?: { chainId: string }): Promise { if (!this.provider) await this.getProvider(); try { if (!this.provider) @@ -168,6 +176,7 @@ export class CoinbaseConnector extends BaseConnector { return { address: address[0]!, walletName: this.name, + chainId: currentId, ecosystem: this.ecosystem, activeConnector: CoinbaseConnector.#instance, }; @@ -224,9 +233,7 @@ export class CoinbaseConnector extends BaseConnector { return { signature: response as string, - activeConnector: CoinbaseConnector.getInstance( - CoinbaseConnector.options - ), + activeConnector: CoinbaseConnector.#instance, }; } catch (error) { console.error(error); diff --git a/packages/evm/src/connectors/injected.ts b/packages/evm/src/connectors/injected.ts index 2a228eb..add5d32 100644 --- a/packages/evm/src/connectors/injected.ts +++ b/packages/evm/src/connectors/injected.ts @@ -1,149 +1,263 @@ -import { hexValue } from "ethers/lib/utils.js"; -import { Web3Provider, ExternalProvider } from "@ethersproject/providers"; -import detectEthereumProvider from "@metamask/detect-provider"; +import { toQuantity, BrowserProvider, hexlify, toUtf8Bytes } from "ethers"; -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, + UserRejectedRequestError, +} from "@wallet01/core"; -import emitter from "../utils/emiter"; -import { chainData } from "../utils/chains"; +import { UnrecognisedChainError } from "../utils/errors"; +import { + AddChainParameter, + ChainSwitchResponse, +} from "@wallet01/core/dist/types/methodTypes"; -export class InjectedConnector extends BaseConnector { - provider?: Web3Provider; +export class InjectedConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: BrowserProvider; - constructor(chain: string = "1") { - super(chain, "injected", "ethereum"); + constructor() { + super("injected", "ethereum"); + } + + static getInstance() { + return this.#instance; + } + + init() { + if (!InjectedConnector.#instance) { + InjectedConnector.#instance = + new InjectedConnector() as BaseConnector; + } + return InjectedConnector.#instance; } async getProvider() { try { - const provider = await detectEthereumProvider(); + if (this.provider) return this.provider; - const _provider = new Web3Provider( - (provider), - "any" - ); - this.provider = _provider; + const windowProvider = window.ethereum; + + if (!windowProvider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const provider = new BrowserProvider(windowProvider); + + this.provider = provider; return this.provider; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); } } async getAccount(): Promise { if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet Not Installed"); - const result = await this.provider.send("eth_requestAccounts", []); - return result; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const accounts = (await this.provider.send( + "eth_requestAccounts", + [] + )) as string[]; + + return accounts; } catch (err) { console.error(err); - throw err; + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } async getChainId(): Promise { - if (this.provider) { - const chainId = await ( - await this.provider.getNetwork() - ).chainId.toString(); - this.chain = chainId; + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const id = (await this.provider.send("eth_chainId", [])) as string; + + const chainId = parseInt(id, 16).toString(); return chainId; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } - return ""; } - async switchChain(chainId: string): Promise { - const provider = await this.getProvider(); - - const id = hexValue(Number(chainId)); + async switchChain( + chainId: string, + options?: AddChainParameter | undefined + ): Promise { + if (!this.provider) await this.getProvider(); try { - await provider?.send("wallet_switchEthereumChain", [{ chainId: id }]); - this.chain = chainId; - } catch (error: any) { - console.log("error in switching chain", error); - if (error.code === 4902 && chainData[chainId]) { - await this.addChain(chainId, provider); - await this.switchChain(chainId); - } else { - throw error; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const oldChainId = await this.getChainId(); + const hexChainId = toQuantity(Number(chainId)); + const params = [{ chainId: hexChainId }]; + + const response = await this.provider.send( + "wallet_switchEthereumChain", + params + ); + + if ((response as any).code === 4902) { + if (!options) { + throw new UnrecognisedChainError({ walletName: this.name, chainId }); + } + + await this.provider.send("wallet_addEthereumChain", [options]); } + + this.emit( + "switchingChain", + oldChainId, + chainId, + InjectedConnector.#instance + ); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: InjectedConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "switchChain", + }); } } - async connect({ chainId }: { chainId: string }) { + async connect(options?: { chainId: string }) { + if (!this.provider) await this.getProvider(); try { - const provider = await this.getProvider(); - this.provider = provider; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const response = await this.provider.send("eth_requestAccounts", []); - if (provider.on) { - provider.on("accountsChanged", this.onAccountsChanged); - provider.on("chainChanged", this.onChainChanged); - provider.on("disconnect", this.onDisconnect); + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); } - let id = await this.getChainId(); + this.provider.on("accountsChanged", this.onAccountsChanged); + this.provider.on("disconnect", this.onDisconnect); + this.provider.on("chainChanged", this.onChainChanged); - if (chainId && id !== chainId) { - await this.switchChain(chainId); + const currentId = await this.getChainId(); + if (options?.chainId && currentId !== options.chainId) { + await this.switchChain(options.chainId); } - setLastUsedConnector(this.name); + const address = await this.getAccount(); - emitter.emit("connected"); - } catch (error) { - console.error(error, "in connect"); - throw error; - } - } - - async disconnect(): Promise { - this.provider = undefined; - emitter.emit("disconnected"); - } + this.emit( + "connected", + address[0]!, + currentId, + this.name, + this.ecosystem, + InjectedConnector.#instance + ); - async resolveDid(address: string): Promise { - try { - if ((await this.getChainId()) !== "1") return null; - const provider = await this.getProvider(); - const name = await provider.lookupAddress(address); - return name; + return { + address: address[0]!, + walletName: this.name, + chainId: currentId, + ecosystem: this.ecosystem, + activeConnector: InjectedConnector.#instance, + }; } catch (error) { - console.error({ error }, "resolveDid"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "connect", + }); } } - async signMessage(message: string): Promise { + async disconnect() { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Connect a wallet!"); - const signer = await this.provider.getSigner(); - const hash = await signer.signMessage(message); - return hash; + await this.provider.destroy(); + this.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); } } - private async addChain(chainId: string, provider: Web3Provider) { + async signMessage(message: string) { + if (!this.provider) await this.getProvider(); try { - await provider.send("wallet_addEthereumChain", [chainData[chainId]]); - } catch (error: any) { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const address = await this.getAccount(); + + const hexMessage = hexlify(toUtf8Bytes(message)); + + const response = await this.provider.send("personal_sign", [ + hexMessage, + address[0], + ]); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + this.emit( + "messageSigned", + response as string, + InjectedConnector.#instance + ); + + return { + signature: response as string, + activeConnector: InjectedConnector.#instance, + }; + } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); } } - protected onAccountsChanged(): void { - console.log("Account Changed"); + protected onAccountsChanged(accounts: string[]): void { + this.emit("accountsChanged", accounts, InjectedConnector.#instance); } - protected onChainChanged(_chain: string): void { - console.log("Chain Changed"); + protected onChainChanged(hexChainId: string): void { + const chainId = parseInt(hexChainId, 16).toString(); + this.emit("chainChanged", chainId, InjectedConnector.#instance); } - protected onDisconnect(): void { - console.log("Wallet disconnected"); + protected onDisconnect(error: any): void { + console.error({ + error, + }); + this.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/okxwallet.ts b/packages/evm/src/connectors/okxwallet.ts index d912d15..f4a1b0b 100644 --- a/packages/evm/src/connectors/okxwallet.ts +++ b/packages/evm/src/connectors/okxwallet.ts @@ -1,147 +1,266 @@ -import { hexValue } from "ethers/lib/utils.js"; -import { Web3Provider, ExternalProvider } from "@ethersproject/providers"; +import { toQuantity, BrowserProvider, hexlify, toUtf8Bytes } from "ethers"; -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, + UserRejectedRequestError, +} from "@wallet01/core"; -import emitter from "../utils/emiter"; -import { chainData } from "../utils/chains"; +import { + AddChainParameter, + ChainSwitchResponse, +} from "@wallet01/core/dist/types/methodTypes"; +import { UnrecognisedChainError } from "../utils/errors"; interface OkxWalletWindow extends Window { - okxwallet?: Web3Provider; + okxwallet?: any; } declare const window: OkxWalletWindow; -export class OkxWalletConnector extends BaseConnector { - provider?: Web3Provider; +export class OkxWalletConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: BrowserProvider; - constructor(chain: string = "1") { - super(chain, "okxwallet", "ethereum"); + constructor() { + super("okxwallet", "ethereum"); + } + + static getInstance() { + return this.#instance; + } + + init() { + if (!OkxWalletConnector.#instance) { + OkxWalletConnector.#instance = + new OkxWalletConnector() as BaseConnector; + } + return OkxWalletConnector.#instance; } async getProvider() { - if (typeof window !== "undefined" && window.okxwallet) { - const provider = window.okxwallet; - const _provider = new Web3Provider((provider)); - this.provider = _provider; + try { + const windowProvider = window.okxwallet; + + if (!windowProvider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const provider = new BrowserProvider(windowProvider); + this.provider = provider; return this.provider; - } else { - throw new Error("Wallet Not Installed"); + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); } } async getAccount(): Promise { if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet Not Installed"); - const result = await this.provider.send("eth_requestAccounts", []); - return result; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const accounts = (await this.provider.send( + "eth_requestAccounts", + [] + )) as string[]; + + return accounts; } catch (err) { console.error(err); - throw err; + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } async getChainId(): Promise { - if (this.provider) { - const chainId = (await this.provider.getNetwork()).chainId.toString(); - this.chain = chainId; + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const id = (await this.provider.send("eth_chainId", [])) as string; + + const chainId = parseInt(id, 16).toString(); return chainId; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } - return ""; } - async switchChain(chainId: string): Promise { - const provider = await this.getProvider(); - - const id = hexValue(Number(chainId)); + async switchChain( + chainId: string, + options?: AddChainParameter | undefined + ): Promise { + if (!this.provider) await this.getProvider(); try { - await provider?.send("wallet_switchEthereumChain", [{ chainId: id }]); - this.chain = chainId; - } catch (error: any) { - console.log("error in switching chain", error); - if (error.code === 4902 && chainData[chainId]) { - await this.addChain(chainId, provider); - await this.switchChain(chainId); - } else { - throw error; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const oldChainId = await this.getChainId(); + const hexChainId = toQuantity(Number(chainId)); + const params = [{ chainId: hexChainId }]; + + const response = await this.provider.send( + "wallet_switchEthereumChain", + params + ); + + if ((response as any).code === 4902) { + if (!options) { + throw new UnrecognisedChainError({ walletName: this.name, chainId }); + } + + await this.provider.send("wallet_addEthereumChain", [options]); } + + this.emit( + "switchingChain", + oldChainId, + chainId, + OkxWalletConnector.#instance + ); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: OkxWalletConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "switchChain", + }); } } - async connect({ chainId }: { chainId: string }) { + async connect(options?: { chainId: string }) { + if (!this.provider) await this.getProvider(); try { - const provider = await this.getProvider(); - this.provider = provider; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const response = await this.provider.send("eth_requestAccounts", []); - if (provider.on) { - provider.on("accountsChanged", this.onAccountsChanged); - provider.on("chainChanged", this.onChainChanged); - provider.on("disconnect", this.onDisconnect); + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); } - let id = await this.getChainId(); + this.provider.on("accountsChanged", this.onAccountsChanged); + this.provider.on("disconnect", this.onDisconnect); + this.provider.on("chainChanged", this.onChainChanged); - if (chainId && id !== chainId) { - await this.switchChain(chainId); + const currentId = await this.getChainId(); + if (options?.chainId && currentId !== options.chainId) { + await this.switchChain(options.chainId); } - setLastUsedConnector(this.name); - - emitter.emit("connected"); - } catch (error) { - console.error(error, "in connect"); - throw error; - } - } + const address = await this.getAccount(); - async disconnect(): Promise { - this.provider = undefined; - emitter.emit("disconnected"); - } + this.emit( + "connected", + address[0]!, + await this.getChainId(), + this.name, + this.ecosystem, + OkxWalletConnector.#instance + ); - async resolveDid(address: string): Promise { - try { - if ((await this.getChainId()) !== "1") return null; - const provider = await this.getProvider(); - const name = await provider.lookupAddress(address); - return name; + return { + address: address[0]!, + walletName: this.name, + chainId: await this.getChainId(), + ecosystem: this.ecosystem, + activeConnector: OkxWalletConnector.#instance, + }; } catch (error) { - console.error({ error }, "resolveDid"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "connect", + }); } } - async signMessage(message: string): Promise { + async disconnect() { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Connect a wallet!"); - const signer = await this.provider.getSigner(); - const hash = await signer.signMessage(message); - return hash; + await this.provider.destroy(); + this.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); } } - private async addChain(chainId: string, provider: Web3Provider) { + async signMessage(message: string) { + if (!this.provider) await this.getProvider(); try { - await provider.send("wallet_addEthereumChain", [chainData[chainId]]); - } catch (error: any) { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const address = await this.getAccount(); + + const hexMessage = hexlify(toUtf8Bytes(message)); + + const response = await this.provider.send("personal_sign", [ + hexMessage, + address[0], + ]); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + this.emit( + "messageSigned", + response as string, + OkxWalletConnector.#instance + ); + + return { + signature: response as string, + activeConnector: OkxWalletConnector.#instance, + }; + } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); } } - protected onAccountsChanged(): void { - console.log("Account Changed"); + protected onAccountsChanged(accounts: string[]): void { + this.emit("accountsChanged", accounts, OkxWalletConnector.#instance); } - protected onChainChanged(_chain: string): void { - console.log("Chain Changed"); + protected onChainChanged(hexChainId: string): void { + const chainId = parseInt(hexChainId, 16).toString(); + this.emit("chainChanged", chainId, OkxWalletConnector.#instance); } - protected onDisconnect(): void { - console.log("Wallet disconnected"); + protected onDisconnect(error: any): void { + console.error({ + error, + }); + this.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/walletconnect.ts b/packages/evm/src/connectors/walletconnect.ts index c954bfd..ee2088e 100644 --- a/packages/evm/src/connectors/walletconnect.ts +++ b/packages/evm/src/connectors/walletconnect.ts @@ -1,13 +1,24 @@ -import { ExternalProvider, Web3Provider } from "@ethersproject/providers"; -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { hexlify, toQuantity, toUtf8Bytes } from "ethers"; + +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, + UserRejectedRequestError, +} from "@wallet01/core"; + import EthereumProvider, { OPTIONAL_METHODS, REQUIRED_METHODS, } from "@walletconnect/ethereum-provider"; import { EthereumProviderOptions } from "@walletconnect/ethereum-provider/dist/types/EthereumProvider"; -// import { hexValue } from "ethers/lib/utils.js"; -import { chainData } from "../utils/chains"; -import { hexlify } from "ethers/lib/utils"; + +import { + AddChainParameter, + ChainSwitchResponse, + ConnectionResponse, + DisconnectionResponse, +} from "@wallet01/core/dist/types/methodTypes"; type WalletconnectConnectorOptions = { chain?: string; @@ -17,37 +28,55 @@ const NAMESPACE = "eip155"; const ADD_ETH_CHAIN_METHOD = "wallet_addEthereumChain"; export class WalletconnectConnector extends BaseConnector { - provider?: EthereumProvider; - private options: EthereumProviderOptions; + static #instance: BaseConnector; + provider!: EthereumProvider; + static options: EthereumProviderOptions; constructor({ chain = "1", chains, projectId, - ...options + ...params }: WalletconnectConnectorOptions) { - super(chain, "walletconnect", "ethereum"); - this.options = { + super("walletconnect", "ethereum"); + WalletconnectConnector.options = { chains, projectId, - optionalChains: options.optionalChains ?? [], - methods: options.methods ?? REQUIRED_METHODS, - optionalMethods: options.optionalMethods ?? OPTIONAL_METHODS, - ...options, + optionalChains: params.optionalChains ?? [], + methods: params.methods ?? REQUIRED_METHODS, + optionalMethods: params.optionalMethods ?? OPTIONAL_METHODS, + ...params, }; + } - this.getProvider(); + static getInstance(options: WalletconnectConnectorOptions) { + WalletconnectConnector.options = options; + return this.#instance; + } + + init() { + if (!WalletconnectConnector.#instance) { + WalletconnectConnector.#instance = new WalletconnectConnector( + WalletconnectConnector.options + ) as BaseConnector; + } + return WalletconnectConnector.#instance; } async getProvider(): Promise { try { - const _provider = await EthereumProvider.init(this.options); + const provider = await EthereumProvider.init( + WalletconnectConnector.options + ); - this.provider = _provider; + this.provider = provider; return this.provider; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); } } @@ -59,118 +88,192 @@ export class WalletconnectConnector extends BaseConnector { return result; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } - async getChainId(): Promise { - if (this.provider) { - const chainId = this.provider.chainId.toString(); - this.chain = chainId; - return chainId; + async getChainId() { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const result = await this.provider.chainId.toString(); + return result; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } - return ""; } - async switchChain(chainId: string): Promise { + async switchChain( + chainId: string, + options?: AddChainParameter | undefined + ): Promise { if (!this.provider) await this.getProvider(); - const _id = hexlify(Number(chainId)); - try { - if (!this.provider) throw new Error("Provider not found"); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const oldChainId = await this.getChainId(); + const hexChainId = toQuantity(Number(chainId)); const namespaceChains = this.getNamespaceChainsIds(); const namespaceMethods = this.getNamespaceMethods(); const isChainApproved = namespaceChains.includes(chainId); if (!isChainApproved && namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) { + if (!namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) + throw new Error( + `${ADD_ETH_CHAIN_METHOD} method was not passed in the options object` + ); + if (!options) + throw new Error( + `Given chainId ${chainId} is not approved and no options object was passed to add the chain` + ); await this.provider.request({ method: ADD_ETH_CHAIN_METHOD, - params: [ - { - ...chainData[chainId], - }, - ], + params: [options], }); } await this.provider.request({ method: "wallet_switchEthereumChain", - params: [{ chainId: _id }], + params: [{ chainId: hexChainId }], }); - this.chain = chainId; + this.emit( + "switchingChain", + oldChainId, + chainId, + WalletconnectConnector.#instance + ); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: WalletconnectConnector.#instance, + }; } catch (error) { - console.error({ error }); - - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "switchChain", + }); } } - async connect({ chainId }: { chainId?: string | undefined }): Promise { + async connect(options?: { chainId: string }): Promise { + if (!this.provider) await this.getProvider(); try { - const provider = await this.getProvider(); - const isStaleChain = this.isChainsStale(); - - if (provider.session && isStaleChain) await provider.disconnect(); - - if (!provider.session || isStaleChain) { - const _chainId = Number(chainId || this.chain); - await provider.connect({ - chains: [_chainId], - optionalChains: this.options.optionalChains, + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const isStaleChain = await this.isChainsStale(); + + if (this.provider.session && isStaleChain) + await this.provider.disconnect(); + + if (!this.provider.session || isStaleChain) { + const chainIdToConnect = Number(options?.chainId || 1); + await this.provider.connect({ + chains: [chainIdToConnect], + optionalChains: WalletconnectConnector.options.optionalChains, }); - - this.chain = _chainId.toString(); + } else { + await this.provider.enable(); + if (options?.chainId && (await this.getChainId()) !== options.chainId) { + await this.switchChain(options.chainId); + } } - await provider.enable(); - this.chain = await this.getChainId(); - const currentId = this.chain; - if (chainId && currentId !== chainId) { - await this.switchChain(chainId); - } - - setLastUsedConnector(this.name); + const accounts = this.provider.accounts; + const currentChainId = await this.getChainId(); + + this.provider.on("disconnect", this.onDisconnect); + this.provider.on("accountsChanged", this.onAccountsChanged); + this.provider.on("chainChanged", this.onChainChanged); + + this.emit( + "connected", + accounts[0]!, + currentChainId, + this.name, + "ethereum", + WalletconnectConnector.#instance + ); + return { + address: accounts[0]!, + chainId: currentChainId, + walletName: this.name, + ecosystem: "ethereum", + activeConnector: WalletconnectConnector.#instance, + }; } catch (error) { console.error(error); throw error; } } - async disconnect(): Promise { - if (!this.provider) throw new Error("Wallet already disconnected"); - await this.provider.disconnect(); - this.provider = undefined; - } - - async resolveDid(address: string): Promise { + async disconnect(): Promise { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet not connected"); - if ((await this.getChainId()) !== "1") return null; - - const _provider = new Web3Provider(this.provider as ExternalProvider); - const name = await _provider.lookupAddress(address); - return name; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + await this.provider.disconnect(); + + this.emit("disconnected", this.name, "ethereum"); + return { + walletName: this.name, + ecosystem: "ethereum", + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); } } - async signMessage(message: string): Promise { + async signMessage(message: string) { + if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet not Connected!"); - const _address = await this.getAccount(); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const address = await this.getAccount(); + + const hexMessage = hexlify(toUtf8Bytes(message)); - const hash = await this.provider.request({ + const response = await this.provider.request({ method: "personal_sign", - params: [_address[0], message], + params: [hexMessage, address[0]], }); - return hash; + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + this.emit( + "messageSigned", + response as string, + WalletconnectConnector.#instance + ); + + return { + signature: response as string, + activeConnector: WalletconnectConnector.#instance, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); } } @@ -188,31 +291,35 @@ export class WalletconnectConnector extends BaseConnector { return methods ?? []; } - private isChainsStale() { + private async isChainsStale() { const namespaceMethods = this.getNamespaceMethods(); if (namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) return false; - const connectorChains = this.chain; + const connectorChains = await this.getChainId(); const namespaceChains = this.getNamespaceChainsIds(); if ( namespaceChains.length && - !namespaceChains.some(id => id === this.chain) + !namespaceChains.some(async id => id === (await this.getChainId())) ) return false; - return !connectorChains.includes(this.chain); + return !connectorChains.includes(await this.getChainId()); } - protected onAccountsChanged(): void { - console.log("Account Changed"); + protected onAccountsChanged(accounts: string[]): void { + this.emit("accountsChanged", accounts, WalletconnectConnector.#instance); } - protected onChainChanged(_chain: string): void { - console.log("Chain Changed"); + protected onChainChanged(hexChainId: string): void { + const chainId = parseInt(hexChainId, 16).toString(); + this.emit("chainChanged", chainId, WalletconnectConnector.#instance); } - protected onDisconnect(): void { - console.log("Wallet disconnected"); + protected onDisconnect(error: any): void { + console.error({ + error, + }); + this.emit("disconnected", this.name, this.ecosystem); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01d4be8..5c7d42a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -238,8 +238,8 @@ importers: specifier: ^2.2.2 version: 2.2.2 ethers: - specifier: ^5.7.2 - version: 5.7.2 + specifier: ^6.7.1 + version: 6.7.1 eventemitter3: specifier: ^4.0.7 version: 4.0.7 @@ -393,6 +393,10 @@ packages: - utf-8-validate dev: false + /@adraffy/ens-normalize@1.9.2: + resolution: {integrity: sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==} + dev: false + /@airgap/beacon-core@4.0.2: resolution: {integrity: sha512-a6mAn6BfbejBQI95tRc6pIZ0VS6MTK9MZ7iXPTLF9hrnCHiROmrCgNKst8qp2dcE0Ehk7z/hGs2WliJzi657YA==} dependencies: @@ -1736,6 +1740,10 @@ packages: resolution: {integrity: sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==} dev: false + /@noble/hashes@1.1.2: + resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} + dev: false + /@noble/hashes@1.1.3: resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} dev: false @@ -1744,6 +1752,10 @@ packages: resolution: {integrity: sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==} dev: false + /@noble/secp256k1@1.7.1: + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2372,6 +2384,10 @@ packages: resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} dev: true + /@types/node@18.15.13: + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + dev: false + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -2947,6 +2963,10 @@ packages: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} dev: false + /aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + dev: false + /agentkeepalive@4.2.1: resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} engines: {node: '>= 8.0.0'} @@ -4646,6 +4666,22 @@ packages: - utf-8-validate dev: false + /ethers@6.7.1: + resolution: {integrity: sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==} + engines: {node: '>=14.0.0'} + dependencies: + '@adraffy/ens-normalize': 1.9.2 + '@noble/hashes': 1.1.2 + '@noble/secp256k1': 1.7.1 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false @@ -7164,6 +7200,10 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + /tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + /tslib@2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} dev: false @@ -7668,6 +7708,19 @@ packages: utf-8-validate: 5.0.10 dev: false + /ws@8.5.0: + resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} From 33a4d491cdfad0d8562cdc350ee34425da5e226e Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Fri, 6 Oct 2023 19:37:22 +0530 Subject: [PATCH 04/17] feat: updating react packages --- examples/nextjs/components/ConnectButtons.tsx | 8 +- examples/nextjs/components/ConnectedModal.tsx | 25 ++-- examples/nextjs/pages/_app.tsx | 36 +++--- examples/nextjs/pages/index.tsx | 16 +-- packages/core/src/store/createWalletSlice.ts | 2 +- packages/core/src/types/methodTypes.ts | 4 +- packages/evm/src/connectors/banana.ts | 18 ++- packages/evm/src/connectors/coinbase.ts | 9 +- packages/evm/src/types/chainConfig.ts | 9 -- packages/evm/src/types/index.ts | 15 --- packages/evm/src/utils/chains.ts | 76 ------------ packages/react/src/context.tsx | 24 ++-- packages/react/src/hooks/index.ts | 13 +- packages/react/src/hooks/useAccount.ts | 31 +++++ packages/react/src/hooks/useClient.ts | 6 +- packages/react/src/hooks/useConnect.ts | 109 +++++++++-------- packages/react/src/hooks/useMessage.ts | 72 +++++++++--- packages/react/src/hooks/useSwitch.ts | 111 ++++++++++-------- packages/react/src/hooks/useWallet.ts | 43 +------ packages/react/src/utils/errors.ts | 41 +++++++ packages/react/tsup.config.ts | 3 +- turbo.json | 8 +- 22 files changed, 330 insertions(+), 349 deletions(-) delete mode 100644 packages/evm/src/types/chainConfig.ts delete mode 100644 packages/evm/src/types/index.ts delete mode 100644 packages/evm/src/utils/chains.ts create mode 100644 packages/react/src/hooks/useAccount.ts create mode 100644 packages/react/src/utils/errors.ts diff --git a/examples/nextjs/components/ConnectButtons.tsx b/examples/nextjs/components/ConnectButtons.tsx index 0de0197..7bf2117 100644 --- a/examples/nextjs/components/ConnectButtons.tsx +++ b/examples/nextjs/components/ConnectButtons.tsx @@ -3,18 +3,14 @@ import { toast } from "react-hot-toast"; import WalletIcons from "./assets/WalletIcons"; const ConnectButtons = () => { - const { connectors, isAutoConnecting } = useClient(); - const { activeConnector, isConnected, did, address } = useWallet(); + const { connectors } = useClient(); + const { activeConnector, isConnected, address } = useWallet(); const { connect, isError, error } = useConnect(); if (isError && error) { toast.error(error.message); } - if (isAutoConnecting) { - console.log("isAutoConnecting"); - } - return (
diff --git a/examples/nextjs/components/ConnectedModal.tsx b/examples/nextjs/components/ConnectedModal.tsx index 5485aca..d31e4bd 100644 --- a/examples/nextjs/components/ConnectedModal.tsx +++ b/examples/nextjs/components/ConnectedModal.tsx @@ -6,10 +6,10 @@ import { BeaconConnector } from "@wallet01/tezos"; const ConnectedModal = () => { const [message, setMessage] = useState(""); const [chainId, setChainId] = useState(""); - const { did, activeConnector, address, disconnect } = useWallet(); - const { signMessage, hash } = useMessage(); - const { switchChain } = useSwitch(); - const { activeChain } = useClient(); + const { activeConnector, address } = useWallet(); + const { signMessage, hash } = useMessage({}); + const { switchChain } = useSwitch({}); + const { ecosystem } = useClient(); return (
@@ -19,18 +19,9 @@ const ConnectedModal = () => {
- {activeChain ? ( - - Connected to {activeChain} - + {ecosystem ? ( + Connected to {ecosystem} ) : null} - {did ? ( - - Hello, {did} - - ) : ( - "" - )} {address ? ( Address:
@@ -42,12 +33,12 @@ const ConnectedModal = () => { {activeConnector?.name === "beacon" ? ( {BeaconConnector.publicKey} ) : null} - + */}
diff --git a/examples/nextjs/pages/_app.tsx b/examples/nextjs/pages/_app.tsx index 20326e1..3d5ee0e 100644 --- a/examples/nextjs/pages/_app.tsx +++ b/examples/nextjs/pages/_app.tsx @@ -9,11 +9,11 @@ import { BananaConnector, OkxWalletConnector, } from "@wallet01/evm"; -import { KeplrConnector } from "@wallet01/cosmos"; -import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; -import { BeaconConnector, TempleConnector } from "@wallet01/tezos"; +// import { KeplrConnector } from "@wallet01/cosmos"; +// import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; +// import { BeaconConnector, TempleConnector } from "@wallet01/tezos"; import Layout from "../components/layout"; -import { ColorMode } from "@wallet01/tezos/dist/types"; +// import { ColorMode } from "@wallet01/tezos/dist/types"; export default function App({ Component, pageProps }: AppProps) { return ( @@ -30,20 +30,22 @@ export default function App({ Component, pageProps }: AppProps) { }), new BananaConnector(), new OkxWalletConnector(), - new CoinbaseConnector(), - new PhantomConnector({ - rpcUrl: "https://api.mainnet-beta.solana.com", - }), - new SolflareConnector({ - rpcUrl: "https://api.mainnet-beta.solana.com", - }), - new KeplrConnector(), - new TempleConnector({ projectName: "Wallet01" }), - new BeaconConnector({ - name: "Wallet01", - featuredWallets: ["temple", "umami", "kukai", "naan"], - colorMode: ColorMode.DARK, + new CoinbaseConnector({ + appName: "Wallet01", }), + // new PhantomConnector({ + // rpcUrl: "https://api.mainnet-beta.solana.com", + // }), + // new SolflareConnector({ + // rpcUrl: "https://api.mainnet-beta.solana.com", + // }), + // new KeplrConnector(), + // new TempleConnector({ projectName: "Wallet01" }), + // new BeaconConnector({ + // name: "Wallet01", + // featuredWallets: ["temple", "umami", "kukai", "naan"], + // colorMode: ColorMode.DARK, + // }), ]} > diff --git a/examples/nextjs/pages/index.tsx b/examples/nextjs/pages/index.tsx index 8b6fec6..a9b8d03 100644 --- a/examples/nextjs/pages/index.tsx +++ b/examples/nextjs/pages/index.tsx @@ -8,19 +8,19 @@ interface SVGIcons { } export default function Home() { - const { isAutoConnecting } = useClient(); + // const { isAutoConnecting } = useClient(); const { isConnected } = useWallet(); + console.log({ + isConnected, + }); + return (
- {isAutoConnecting ? ( + {/* {isAutoConnecting ? ( AutoConnecting - ) : null} - {isConnected && !isAutoConnecting ? ( - - ) : ( - - )} + ) : null} */} + {isConnected ? : }
); } diff --git a/packages/core/src/store/createWalletSlice.ts b/packages/core/src/store/createWalletSlice.ts index ed8c8f5..fb0e608 100644 --- a/packages/core/src/store/createWalletSlice.ts +++ b/packages/core/src/store/createWalletSlice.ts @@ -8,7 +8,7 @@ const createWalletSlice: StateCreator< IWalletState > = set => ({ isConnected: false, - chainId: "default", + chainId: "mainnet", setIsConnected: isConnected => { set(() => ({ isConnected })); }, diff --git a/packages/core/src/types/methodTypes.ts b/packages/core/src/types/methodTypes.ts index 8b06dd5..69e0920 100644 --- a/packages/core/src/types/methodTypes.ts +++ b/packages/core/src/types/methodTypes.ts @@ -40,7 +40,7 @@ export type MessageSignedResponse = { }; export type ChainSwitchResponse = { - fromChainId: string | "default"; - toChainId: string | "default"; + fromChainId: string | "mainnet"; + toChainId: string | "mainnet"; activeConnector: BaseConnector; }; diff --git a/packages/evm/src/connectors/banana.ts b/packages/evm/src/connectors/banana.ts index 47239d6..0bb6786 100644 --- a/packages/evm/src/connectors/banana.ts +++ b/packages/evm/src/connectors/banana.ts @@ -1,6 +1,7 @@ import { BaseConnector, ProviderNotFoundError, + UnknownError, WalletConnectionError, WalletNotConnectedError, } from "@wallet01/core"; @@ -155,11 +156,20 @@ export class BananaConnector extends BaseConnector { } async getChainId(): Promise { - if (this.provider) { - const id = this.provider.chainId.toString(); - return id; + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const chainId = this.provider.chainId.toString(); + return chainId; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } - return ""; } //! Currently Banana wallet has 1:1 mapping with account diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index 971b0a9..3884ee7 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -13,8 +13,11 @@ import { AddChainParameter, ConnectionResponse, } from "@wallet01/core/dist/types/methodTypes"; -export class CoinbaseConnector extends BaseConnector { - static #instance: BaseConnector; +export class CoinbaseConnector extends BaseConnector< + CoinbaseWalletProvider, + "coinbase" +> { + static #instance: BaseConnector; static options: CoinbaseWalletSDKOptions; provider!: CoinbaseWalletProvider; @@ -27,7 +30,7 @@ export class CoinbaseConnector extends BaseConnector { if (!CoinbaseConnector.#instance) { CoinbaseConnector.#instance = new CoinbaseConnector( CoinbaseConnector.options - ) as BaseConnector; + ) as BaseConnector; } return CoinbaseConnector.#instance; } diff --git a/packages/evm/src/types/chainConfig.ts b/packages/evm/src/types/chainConfig.ts deleted file mode 100644 index f91530f..0000000 --- a/packages/evm/src/types/chainConfig.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type CustomChainConfig = { - chainNamespace: 'eip155' | 'solana' | 'other'; - chainId: string; - rpcTarget?: string; - displayName: string; - blockExplorer?: string; - ticker: string; - tickerName: string; -}; diff --git a/packages/evm/src/types/index.ts b/packages/evm/src/types/index.ts deleted file mode 100644 index e454ea7..0000000 --- a/packages/evm/src/types/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CustomChainConfig } from './chainConfig'; -import { BaseConnector } from '@wallet01/core'; - -type ClientConfig = { - chainConfig: CustomChainConfig; - connector: BaseConnector; -}; - -type ConnectedData = { - account: string; - chainId: string; - provider: TProvider; -}; - -export { type CustomChainConfig, type ClientConfig, type ConnectedData }; diff --git a/packages/evm/src/utils/chains.ts b/packages/evm/src/utils/chains.ts deleted file mode 100644 index f601561..0000000 --- a/packages/evm/src/utils/chains.ts +++ /dev/null @@ -1,76 +0,0 @@ -interface ChainData { - chainId: string; - chainName: string; - nativeCurrency: { - name: string; - symbol: string; - decimals: number; - }; - rpcUrls: string[]; - blockExplorerUrls: string[]; -} - -interface ChainObj { - [name: string]: ChainData; -} - -export const chainData: ChainObj = { - "3141": { - chainId: "0x7ab7", - chainName: "Wallaby filecoin", - nativeCurrency: { - name: "Test FIlecoin", - symbol: "tFIL", - decimals: 18, - }, - rpcUrls: [`https://wallaby.node.glif.io/rpc/v0`], - blockExplorerUrls: [ - "https://wallaby.filscan.io", - "https://explorer.glif.io/actor/?network=wallaby", - ], - }, - "137": { - chainId: "0x89", - chainName: "Matic Mainnet", - nativeCurrency: { - name: "Matic", - symbol: "MATIC", - decimals: 18, - }, - rpcUrls: [`https://polygon.llamarpc.com`], - blockExplorerUrls: [`https://polygonscan.com`], - }, - "80001": { - chainId: "0x13881", - chainName: "Mumbai", - nativeCurrency: { - name: "Matic", - symbol: "MATIC", - decimals: 18, - }, - rpcUrls: [`https://rpc-mumbai.maticvigil.com`], - blockExplorerUrls: [`https://mumbai.polygonscan.com`], - }, - "303": { - chainId: "0x12f", - chainName: "WYZth Scan", - nativeCurrency: { - name: "WYZ", - symbol: "WYZ", - decimals: 18, - }, - rpcUrls: [`https://rpc-mainnet.wyzthchain.org`], - blockExplorerUrls: [`https://wyzthscan.org`], - }, - "8081": { - chainId: "0x1f91", - chainName: "Shardeum Sphinx Dapp 1.X", - nativeCurrency: { - name: "SHM", - symbol: "SHM", - decimals: 18, - }, - rpcUrls: [`https://dapps.shardeum.org`], - blockExplorerUrls: [`https://explorer-dapps.shardeum.org`], - } -}; diff --git a/packages/react/src/context.tsx b/packages/react/src/context.tsx index e3bed58..cf8cab4 100644 --- a/packages/react/src/context.tsx +++ b/packages/react/src/context.tsx @@ -1,12 +1,15 @@ -import React, { FunctionComponent, useEffect } from 'react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { BaseConnector, Client } from '@wallet01/core'; +"use client"; +import React, { FunctionComponent, useEffect, useState } from "react"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BaseConnector, Client } from "@wallet01/core"; interface Props { children: JSX.Element; autoConnect: boolean; connectors: BaseConnector[] | (() => BaseConnector[]); } + +export const ClientProvider = React.createContext(null); /** * @description A context that wraps your app under wallet01 states and providers */ @@ -17,16 +20,23 @@ const Wallet01: FunctionComponent = ({ }) => { // if (typeof window === 'undefined') <>{children}; const [queryClient] = React.useState(() => new QueryClient()); + const [wallet01Client, setWalletClient] = useState(null); useEffect(() => { - Client.init({ + const client = Client.init({ autoConnect, - connectors: typeof connectors === 'function' ? connectors() : connectors, + connectors: typeof connectors === "function" ? connectors() : connectors, }); - }, []); + + setWalletClient(client); + }, [connectors]); return ( - {children} + + + {children} + + ); }; diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index f7d04f6..696d87f 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -1,10 +1,7 @@ -import { useConnect } from './useConnect'; -import { useMessage } from './useMessage'; -import { useSwitch } from './useSwitch'; -import { useClient } from './useClient'; -import { useWallet } from './useWallet'; -// import { initClientAtom } from '../store/clientStore'; +import { useConnect } from "./useConnect"; +import { useMessage } from "./useMessage"; +import { useSwitch } from "./useSwitch"; +import { useClient } from "./useClient"; +import { useWallet } from "./useWallet"; export { useConnect, useMessage, useSwitch, useClient, useWallet }; - -// export const useInitClient = () => useSetAtom(initClientAtom); diff --git a/packages/react/src/hooks/useAccount.ts b/packages/react/src/hooks/useAccount.ts new file mode 100644 index 0000000..c9802b5 --- /dev/null +++ b/packages/react/src/hooks/useAccount.ts @@ -0,0 +1,31 @@ +import { BaseConnector, useStore } from "@wallet01/core"; +import { ClientProvider } from "../context"; +import { useContext, useEffect } from "react"; +import { ClientNotFoundError } from "../utils/errors"; + +type useAccountConfig = { + onAccountChange?: ( + address: string[], + activeConnector: BaseConnector + ) => Promise | void; +}; + +export const userAccount = ({}: useAccountConfig) => { + const client = useContext(ClientProvider); + const { address, addresses, activeConnector } = useStore(); + + useEffect(() => { + if (!client) throw new ClientNotFoundError(); + + // if (onAccountChange) + // client.on("accountsChanged", (address, activeConnector) => + // onAccountChange(address, activeConnector) + // ); + }, [activeConnector, client]); + + return { + address, + addresses, + activeConnector, + }; +}; diff --git a/packages/react/src/hooks/useClient.ts b/packages/react/src/hooks/useClient.ts index 38a551e..78c3d24 100644 --- a/packages/react/src/hooks/useClient.ts +++ b/packages/react/src/hooks/useClient.ts @@ -1,11 +1,11 @@ import { useStore } from "@wallet01/core"; export const useClient = () => { - const { connectors, isAutoConnecting, activeChain } = useStore(); + const { connectors, ecosystem, activeConnector } = useStore(); return { connectors, - isAutoConnecting, - activeChain, + ecosystem, + activeConnector, }; }; diff --git a/packages/react/src/hooks/useConnect.ts b/packages/react/src/hooks/useConnect.ts index 02c9396..7c1fd37 100644 --- a/packages/react/src/hooks/useConnect.ts +++ b/packages/react/src/hooks/useConnect.ts @@ -1,90 +1,87 @@ -import { BaseConnector, useStore } from "@wallet01/core"; +import { BaseConnector } from "@wallet01/core"; import { useMutation, UseMutationOptions } from "@tanstack/react-query"; +import { useCallback, useContext } from "react"; +import { ClientProvider } from "../context"; +import { ClientNotFoundError, ConnectorNotFoundError } from "../utils/errors"; +import { ConnectionResponse } from "@wallet01/core/dist/types/methodTypes"; type ConnectArgs = { - connector: BaseConnector | undefined; - chainId?: string; -}; - -type ConnectResult = { - address: string; - chain: "ethereum" | "solana" | "cosmos" | "tezos"; connector: BaseConnector; + chainId?: string; }; type UseConenctConfig = { onError?: UseMutationOptions["onError"]; - onSuccess?: UseMutationOptions["onSuccess"]; + onConnect?: (params: ConnectionResponse) => Promise | void; }; export const useConnect = ({ onError, - onSuccess, -}: Partial = {}) => { - const { - connectors, - setActiveConnector, - setIsConnected, - setAddress, - setDid, - setChainId, - setActiveChain, - } = useStore(); +} // onConnect, +: Partial = {}) => { + const client = useContext(ClientProvider); const { mutate, mutateAsync, isLoading, isError, error } = useMutation< - ConnectResult, + ConnectionResponse, Error, ConnectArgs, unknown >({ mutationFn: async ({ connector, chainId }: ConnectArgs) => { - if (connectors.length === 0) throw new Error("Client not initialised"); - - if (!connector) throw new Error("Connector required to connect"); - setActiveConnector(connector); - - if (!connectors.includes(connector)) - throw new Error("Connector not found"); + try { + if (!client) throw new ClientNotFoundError(); - if (chainId) { - await connector.connect({ chainId: chainId }); - } else { - await connector.connect({}); - } + const connectors = client.store.getConnectors(); - const address = (await connector.getAccount())[0]; - const chain = connector.activeChain; + if (!connectors.includes(connector)) + throw new ConnectorNotFoundError({ connectorName: connector.name }); - if (!address) throw new Error("No account found"); + let connectionResult: ConnectionResponse; - setAddress(address); + if (chainId) { + connectionResult = await connector.connect({ chainId: chainId }); + } else { + connectionResult = await connector.connect(); + } - setActiveChain(connector.activeChain); - setIsConnected(true); + // if (onConnect) + // client.on( + // "connected", + // (address, chainId, walletName, ecosystem, activeConnector) => + // onConnect({ + // activeConnector, + // address, + // chainId, + // ecosystem, + // walletName, + // }) + // ); - setDid( - await connector.resolveDid(address).catch(error => { - console.error({ error }); - return null; - }) - ); - if (connector.getChainId) { - setChainId(await connector.getChainId()); + return connectionResult; + } catch (error) { + throw error; } - - return { - address, - chain, - connector, - }; }, onError, - onSuccess, }); + const connect = useCallback( + (params?: ConnectArgs) => { + return mutate(params as ConnectArgs); + }, + [client] + ); + + const connectAsync = useCallback( + (params?: ConnectArgs) => { + return mutateAsync(params as ConnectArgs); + }, + [client] + ); + return { - connect: mutate, - connectAsync: mutateAsync, + connect, + connectAsync, isLoading, isError, error, diff --git a/packages/react/src/hooks/useMessage.ts b/packages/react/src/hooks/useMessage.ts index 5044560..1c03cf9 100644 --- a/packages/react/src/hooks/useMessage.ts +++ b/packages/react/src/hooks/useMessage.ts @@ -1,5 +1,19 @@ -import { useMutation } from '@tanstack/react-query'; -import { useStore } from '@wallet01/core'; +import { UseMutationOptions, useMutation } from "@tanstack/react-query"; +import { useCallback, useContext } from "react"; +import { ClientProvider } from "../context"; +import { ClientNotFoundError, NoWalletConnectedError } from "../utils/errors"; +import { MessageSignedResponse } from "@wallet01/core/dist/types/methodTypes"; +interface SignMessageArgs { + message: string; +} + +interface useMessageConfig { + onError?: UseMutationOptions["onError"]; + onMessageSigned?: ({ + activeConnector, + signature, + }: MessageSignedResponse) => void; +} /** * @description This hooks will return signMessage function that helps sign messages from desired wallet. * @params Accepts an object with properties connector and message @@ -8,39 +22,59 @@ import { useStore } from '@wallet01/core'; * For more details visit {@link} */ -interface SignMessageArgs { - message: string; -} - -export const useMessage = () => { - const { connectors, activeConnector } = useStore(); +export const useMessage = ({ onError }: useMessageConfig) => { + const client = useContext(ClientProvider); const { data, isLoading, isError, mutate, mutateAsync, error } = useMutation< - string, + MessageSignedResponse, Error, SignMessageArgs, unknown >({ mutationFn: async ({ message }: SignMessageArgs) => { - // if (!client) throw new Error('Client not Initialised'); + try { + if (!client) throw new ClientNotFoundError(); - if (!activeConnector) throw new Error('Wallet not connected'); + const activeConnector = client.store.getActiveConnector(); - if (!connectors.includes(activeConnector)) { - throw new Error('Connector not found'); - } + if (!activeConnector) + throw new NoWalletConnectedError({ methodName: "signMessage" }); + + const response = await activeConnector.signMessage(message); - const hash = await activeConnector.signMessage(message); - return hash; + // if (onMessageSigned) + // client.on("messageSigned", (signature, activeConnector) => + // onMessageSigned({ signature, activeConnector }) + // ); + + return response; + } catch (error) { + throw error; + } }, + onError, }); + const signMessage = useCallback( + (params: SignMessageArgs) => { + return mutate(params); + }, + [client] + ); + + const signMessageAsync = useCallback( + (params: SignMessageArgs) => { + return mutateAsync(params); + }, + [client] + ); + return { - hash: data, + hash: data?.signature, isLoading, isError, error: error?.message, - signMessage: mutate, - signMessageAsync: mutateAsync, + signMessage, + signMessageAsync, }; }; diff --git a/packages/react/src/hooks/useSwitch.ts b/packages/react/src/hooks/useSwitch.ts index 0859132..860d527 100644 --- a/packages/react/src/hooks/useSwitch.ts +++ b/packages/react/src/hooks/useSwitch.ts @@ -1,5 +1,21 @@ -import { useMutation } from "@tanstack/react-query"; -import { useStore } from "@wallet01/core"; +import { UseMutationOptions, useMutation } from "@tanstack/react-query"; +import { ChainSwitchResponse } from "@wallet01/core/dist/types/methodTypes"; +import { useCallback, useContext } from "react"; +import { ClientProvider } from "../context"; +import { + ClientNotFoundError, + NoWalletConnectedError, + UnsupportedFunctionCalledError, +} from "../utils/errors"; + +interface ChainSwitchArgs { + chainId: string; +} + +interface useMessageConfig { + onError?: UseMutationOptions["onError"]; + onChainSwitched?: (params: ChainSwitchResponse) => void; +} /** * @description This hooks will return switchChain function that will help chain in your desired wallet. @@ -9,74 +25,71 @@ import { useStore } from "@wallet01/core"; * For more details visit {@link} */ -interface ChainSwitchArgs { - chainId: string; -} - -export const useSwitch = () => { - const { - connectors, - activeConnector, - setAddress, - setIsConnected, - setDid, - setChainId, - } = useStore(); +export const useSwitch = ({ onError }: useMessageConfig) => { + const client = useContext(ClientProvider); const { isLoading, isError, error, mutate, mutateAsync } = useMutation< - string, + ChainSwitchResponse, Error, ChainSwitchArgs, unknown >({ mutationFn: async ({ chainId }: ChainSwitchArgs) => { - // if (!client) throw new Error('Client not Initialised'); + try { + if (!client) throw new ClientNotFoundError(); - if (!activeConnector) throw new Error("Wallet not connected"); + const activeConnector = client.store.getActiveConnector(); + const connectors = client.store.getConnectors(); - if (!connectors.includes(activeConnector)) { - throw new Error("Connector not found"); - } + if (!activeConnector) + throw new NoWalletConnectedError({ methodName: "switchChain" }); - if (!activeConnector.switchChain) - throw new Error("Function not supported by wallet"); + if (!connectors.includes(activeConnector)) { + throw new Error("Connector not found"); + } - await activeConnector.switchChain(chainId); - setIsConnected(false); + if (!activeConnector.switchChain) + throw new UnsupportedFunctionCalledError({ + methodName: "switchChain", + walletName: activeConnector.name, + }); - const address = (await activeConnector.getAccount())[0]; + // if (onChainSwitched) + // client.on( + // "switchingChain", + // (fromChainId, toChainId, activeConnector) => + // onChainSwitched({ fromChainId, toChainId, activeConnector }) + // ); - if (!address) throw new Error("No account found"); + const response = await activeConnector.switchChain(chainId); - setAddress(address); + return response; + } catch (error) { + throw error; + } + }, + onError, + }); - setDid( - address - ? await activeConnector.resolveDid(address).catch(error => { - console.error({ error }); - return null; - }) - : null - ); - setChainId( - activeConnector.getChainId - ? await activeConnector.getChainId().catch(error => { - console.error({ error }); - return null; - }) - : null - ); - setIsConnected(true); + const switchChain = useCallback( + (params: ChainSwitchArgs) => { + return mutate(params); + }, + [client] + ); - return address; + const switchChainAsync = useCallback( + (params: ChainSwitchArgs) => { + return mutateAsync(params); }, - }); + [client] + ); return { isLoading, isError, error, - switchChain: mutate, - switchChainAsync: mutateAsync, + switchChain, + switchChainAsync, }; }; diff --git a/packages/react/src/hooks/useWallet.ts b/packages/react/src/hooks/useWallet.ts index ef258fe..2a9a3ca 100644 --- a/packages/react/src/hooks/useWallet.ts +++ b/packages/react/src/hooks/useWallet.ts @@ -1,51 +1,14 @@ -import { useMutation } from "@tanstack/react-query"; import { useStore } from "@wallet01/core"; export const useWallet = () => { - const { - did, - chainId, - address, - connectors, - isConnected, - activeConnector, - setDid, - setAddress, - setChainId, - setIsConnected, - setActiveConnector, - setActiveChain, - setIsAutoConnecting, - } = useStore(); - - const { mutate } = useMutation({ - mutationFn: async () => { - // if (!client) throw new Error('Client not Initialised'); - - if (!activeConnector) throw new Error("Wallet not connected"); - - if (!connectors.includes(activeConnector)) { - throw new Error("Connector not found"); - } - - await activeConnector.disconnect(); - setActiveConnector(null); - setAddress(null); - setChainId(null); - setDid(null); - setActiveChain(null); - setIsConnected(false); - setIsAutoConnecting(false); - localStorage.setItem("lastUsedConnector", ""); - }, - }); + const { chainId, address, isConnected, activeConnector } = useStore(); return { + walletName: activeConnector?.name, + ecosystem: activeConnector?.ecosystem, isConnected, address, - did, chainId, activeConnector, - disconnect: mutate, }; }; diff --git a/packages/react/src/utils/errors.ts b/packages/react/src/utils/errors.ts new file mode 100644 index 0000000..3ddefd7 --- /dev/null +++ b/packages/react/src/utils/errors.ts @@ -0,0 +1,41 @@ +export class ClientNotFoundError extends Error { + name = "ClientNotFoundError"; + constructor() { + super( + "Wallet01Client has not been initialised. Please initialise the client to use the hooks." + ); + } +} + +export class ConnectorNotFoundError extends Error { + name = "ConnectorNotFoundError"; + constructor({ connectorName }: { connectorName: string }) { + super( + `Connector ${connectorName} not found. Please check your Wallet01Client config.` + ); + } +} + +export class NoWalletConnectedError extends Error { + name = "NoWalletConnectedError"; + constructor({ methodName }: { methodName: string }) { + super( + `No wallet connected. Please connect a wallet to use ${methodName} method.` + ); + } +} + +export class UnsupportedFunctionCalledError extends Error { + name = "UnsupportedFunctionCalledError"; + constructor({ + methodName, + walletName, + }: { + methodName: string; + walletName: string; + }) { + super( + `Function ${methodName} is not supported by the ${walletName} wallet.` + ); + } +} diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index 3fe8046..529c8d0 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -7,8 +7,7 @@ export default defineConfig({ format: ["cjs", "esm"], // generate cjs and esm files bundle: true, skipNodeModulesBundle: true, - entryPoints: ["src/index.ts"], target: "es2020", outDir: "dist", - entry: ["src/**/*.ts"], //include all files under src + entry: ["src/*index.ts"], //include all files under src }); diff --git a/turbo.json b/turbo.json index e9487a3..a54abff 100644 --- a/turbo.json +++ b/turbo.json @@ -18,13 +18,7 @@ "dependsOn": ["@wallet01/core#build"] }, "@wallet01/react#build": { - "dependsOn": [ - "@wallet01/core#build", - "@wallet01/evm#build", - "@wallet01/cosmos#build", - "@wallet01/solana#build", - "@wallet01/tezos#build" - ], + "dependsOn": ["@wallet01/core#build"], "outputs": [] }, "lint": { From 4931b166fad667f1845f6fa997c4645bd36c66eb Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Wed, 11 Oct 2023 14:21:20 +0530 Subject: [PATCH 05/17] fix: event emitter has a singleton instance among classes; react build fixed; add: useDisconnect and useChain hooks --- .eslintrc.js | 4 +- examples/nextjs/components/ConnectedModal.tsx | 8 ++- examples/nextjs/pages/_app.tsx | 11 ++-- packages/core/src/client/client.ts | 26 +++++---- packages/core/src/types/BaseConnector.ts | 9 ++- .../core/src/utils/EnhancedEventEmitter.ts | 12 +++- packages/evm/src/connectors/banana.ts | 18 +++--- packages/evm/src/connectors/coinbase.ts | 23 +++----- packages/evm/src/connectors/injected.ts | 20 +++---- packages/evm/src/connectors/okxwallet.ts | 24 ++++---- packages/evm/src/connectors/walletconnect.ts | 53 +++++++++-------- packages/react/src/context.tsx | 2 + packages/react/src/hooks/useAccount.ts | 7 +-- packages/react/src/hooks/useChain.ts | 24 ++++++++ packages/react/src/hooks/useConnect.ts | 55 ++++++++---------- packages/react/src/hooks/useDisconnect.ts | 57 +++++++++++++++++++ packages/react/src/hooks/useMessage.ts | 43 +++++++------- packages/react/src/hooks/useSwitch.ts | 19 ++++--- packages/react/tsup.config.ts | 2 +- 19 files changed, 250 insertions(+), 167 deletions(-) create mode 100644 packages/react/src/hooks/useChain.ts create mode 100644 packages/react/src/hooks/useDisconnect.ts diff --git a/.eslintrc.js b/.eslintrc.js index a2845bf..7d48c6d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,10 +1,10 @@ module.exports = { root: true, // This tells ESLint to load the config from the package `eslint-config-custom` - extends: ['custom'], + extends: ["custom"], settings: { next: { - rootDir: ['apps/*/'], + rootDir: ["examples/*/", "packages/*/"], }, }, }; diff --git a/examples/nextjs/components/ConnectedModal.tsx b/examples/nextjs/components/ConnectedModal.tsx index d31e4bd..9325f4f 100644 --- a/examples/nextjs/components/ConnectedModal.tsx +++ b/examples/nextjs/components/ConnectedModal.tsx @@ -6,7 +6,7 @@ import { BeaconConnector } from "@wallet01/tezos"; const ConnectedModal = () => { const [message, setMessage] = useState(""); const [chainId, setChainId] = useState(""); - const { activeConnector, address } = useWallet(); + const { activeConnector, address, chainId: cId } = useWallet(); const { signMessage, hash } = useMessage({}); const { switchChain } = useSwitch({}); const { ecosystem } = useClient(); @@ -30,6 +30,12 @@ const ConnectedModal = () => { ) : ( "" )} + { + + ChainId:
+ {cId} +
+ } {activeConnector?.name === "beacon" ? ( {BeaconConnector.publicKey} ) : null} diff --git a/examples/nextjs/pages/_app.tsx b/examples/nextjs/pages/_app.tsx index 3d5ee0e..d469604 100644 --- a/examples/nextjs/pages/_app.tsx +++ b/examples/nextjs/pages/_app.tsx @@ -20,17 +20,16 @@ export default function App({ Component, pageProps }: AppProps) { [ - new InjectedConnector(), - new WalletconnectConnector({ - chain: "1", + InjectedConnector.init(), + WalletconnectConnector.init({ chains: [1], optionalChains: [137, 80001], projectId: "cef77f9c3969fb563468d997449c92d2", showQrModal: true, }), - new BananaConnector(), - new OkxWalletConnector(), - new CoinbaseConnector({ + BananaConnector.init(), + OkxWalletConnector.init(), + CoinbaseConnector.init({ appName: "Wallet01", }), // new PhantomConnector({ diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index 61cb8f2..6c7e4ed 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -3,16 +3,18 @@ import { ClientConfig } from "../types/methodTypes"; import { EnhancedEventEmitter } from "../utils/EnhancedEventEmitter"; import { Wallet01Store } from "./store"; -export default class Wallet01Client extends EnhancedEventEmitter< - ClientEvents & ConnectorEvents -> { +export default class Wallet01Client { static #instance: Wallet01Client; + public readonly emitter: EnhancedEventEmitter; public store: Wallet01Store = Wallet01Store.init(); constructor({ autoConnect = false, connectors }: ClientConfig) { - super(); + this.emitter = EnhancedEventEmitter.init(); this.store.setConnectors(connectors); + + console.log("Creating client class"); + this.registerEventListeners(); if (localStorage.getItem("autoConnect") === null) @@ -45,7 +47,7 @@ export default class Wallet01Client extends EnhancedEventEmitter< private registerEventListeners() { // this.on("isAutoConnecting", (ecosystem) => {}) - this.on( + this.emitter.on( "connected", (address, chainId, walletName, ecosystem, activeConnector) => { localStorage.setItem("lastUsedConnector", walletName); @@ -57,21 +59,20 @@ export default class Wallet01Client extends EnhancedEventEmitter< } ); - this.on("disconnected", () => { + this.emitter.on("disconnected", () => { localStorage.removeItem("lastUsedConnector"); this.store.setActiveConnector(null); this.store.setAddress(null); this.store.setChainId(null); this.store.setEcosystem(null); this.store.setIsConnected(false); - this.removeAllListeners(); }); - this.on("chainChanged", chainId => { + this.emitter.on("chainChanged", chainId => { this.store.setChainId(chainId); }); - this.on("accountsChanged", addresses => { + this.emitter.on("accountsChanged", addresses => { this.store.setAddresses(addresses); }); } @@ -102,9 +103,12 @@ export default class Wallet01Client extends EnhancedEventEmitter< const activeConnector = this.store.getActiveConnector(); if (activeConnector) { - this.emit("isAutoConnecting", activeConnector.ecosystem, activeConnector); + this.emitter.emit( + "isAutoConnecting", + activeConnector.ecosystem, + activeConnector + ); - await activeConnector.init(); await activeConnector.connect(); } } diff --git a/packages/core/src/types/BaseConnector.ts b/packages/core/src/types/BaseConnector.ts index 9f4f61f..b3f37bd 100644 --- a/packages/core/src/types/BaseConnector.ts +++ b/packages/core/src/types/BaseConnector.ts @@ -7,24 +7,23 @@ import { DisconnectionResponse, MessageSignedResponse, } from "./methodTypes"; -import { ConnectorEvents } from "./events"; +import { ClientEvents, ConnectorEvents } from "./events"; export abstract class BaseConnector< TProvider extends {} = {}, TWalletName extends string = string, -> extends EnhancedEventEmitter { +> { abstract provider: TProvider; readonly name: TWalletName; readonly ecosystem: TEcosystem; + readonly emitter: EnhancedEventEmitter = + EnhancedEventEmitter.init(); constructor(name: TWalletName, ecosystem: TEcosystem) { - super(); this.name = name; this.ecosystem = ecosystem; } - abstract init(): BaseConnector; - abstract connect(options?: { chainId: string }): Promise; abstract disconnect(): Promise; diff --git a/packages/core/src/utils/EnhancedEventEmitter.ts b/packages/core/src/utils/EnhancedEventEmitter.ts index fd96459..9fb12ca 100644 --- a/packages/core/src/utils/EnhancedEventEmitter.ts +++ b/packages/core/src/utils/EnhancedEventEmitter.ts @@ -1,8 +1,10 @@ import { EventEmitter } from "events"; +import { ClientEvents, ConnectorEvents } from "../types/events"; export type Events = Record; -class EnhancedEventEmitter { +class EnhancedEventEmitter { + static #instance: EnhancedEventEmitter; private emitter: EventEmitter; constructor() { @@ -10,6 +12,14 @@ class EnhancedEventEmitter { this.emitter.setMaxListeners(Infinity); } + static init = () => { + if (!EnhancedEventEmitter.#instance) + EnhancedEventEmitter.#instance = new EnhancedEventEmitter< + ConnectorEvents & ClientEvents + >(); + return EnhancedEventEmitter.#instance; + }; + public on( eventName: K, listener: (...args: E[K]) => void diff --git a/packages/evm/src/connectors/banana.ts b/packages/evm/src/connectors/banana.ts index 0bb6786..5025c01 100644 --- a/packages/evm/src/connectors/banana.ts +++ b/packages/evm/src/connectors/banana.ts @@ -29,7 +29,7 @@ export class BananaConnector extends BaseConnector { super("banana", "ethereum"); } - init() { + static init() { if (!BananaConnector.#instance) { BananaConnector.#instance = new BananaConnector() as BaseConnector; @@ -37,10 +37,6 @@ export class BananaConnector extends BaseConnector { return BananaConnector.#instance; } - static getInstance() { - return this.#instance; - } - async getProvider(): Promise { if (!this.provider) { throw new ProviderNotFoundError({ walletName: this.name }); @@ -76,13 +72,13 @@ export class BananaConnector extends BaseConnector { const address = await this.wallet.getAddress(); const chainId = await this.getChainId(); - this.emit( + this.emitter.emit( "connected", address, chainId, this.name, this.ecosystem, - BananaConnector.getInstance() + BananaConnector.#instance ); return { @@ -90,7 +86,7 @@ export class BananaConnector extends BaseConnector { walletName: this.name, chainId, ecosystem: this.ecosystem, - activeConnector: BananaConnector.getInstance(), + activeConnector: BananaConnector.#instance, }; } @@ -108,7 +104,7 @@ export class BananaConnector extends BaseConnector { // connect to same wallet with new configs const connection = await this.connect(); - this.emit("chainChanged", chainId, BananaConnector.getInstance()); + this.emitter.emit("chainChanged", chainId, BananaConnector.#instance); return { fromChainId: oldChainId, @@ -125,7 +121,7 @@ export class BananaConnector extends BaseConnector { return { signature: hash, - activeConnector: BananaConnector.getInstance(), + activeConnector: BananaConnector.#instance, }; } catch (error) { console.error(error); @@ -182,6 +178,6 @@ export class BananaConnector extends BaseConnector { } protected onDisconnect(): void { - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index 3884ee7..cb1e3af 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -26,20 +26,15 @@ export class CoinbaseConnector extends BaseConnector< CoinbaseConnector.options = options; } - init() { + static init(options: CoinbaseWalletSDKOptions) { if (!CoinbaseConnector.#instance) { CoinbaseConnector.#instance = new CoinbaseConnector( - CoinbaseConnector.options + options ) as BaseConnector; } return CoinbaseConnector.#instance; } - static getInstance(options: CoinbaseWalletSDKOptions) { - this.options = options; - return CoinbaseConnector.#instance; - } - async getProvider(): Promise { try { if (this.provider) return this.provider; @@ -121,7 +116,7 @@ export class CoinbaseConnector extends BaseConnector< }); } - this.emit( + this.emitter.emit( "switchingChain", oldChainId, chainId, @@ -167,7 +162,7 @@ export class CoinbaseConnector extends BaseConnector< const address = await this.getAccount(); - this.emit( + this.emitter.emit( "connected", address[0]!, currentId, @@ -196,7 +191,7 @@ export class CoinbaseConnector extends BaseConnector< if (!this.provider) await this.getProvider(); try { await this.provider.disconnect(); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); return { walletName: this.name, ecosystem: this.ecosystem, @@ -228,7 +223,7 @@ export class CoinbaseConnector extends BaseConnector< throw new UserRejectedRequestError(); } - this.emit( + this.emitter.emit( "messageSigned", response as string, CoinbaseConnector.#instance @@ -248,18 +243,18 @@ export class CoinbaseConnector extends BaseConnector< } protected onAccountsChanged(accounts: string[]): void { - this.emit("accountsChanged", accounts, CoinbaseConnector.#instance); + this.emitter.emit("accountsChanged", accounts, CoinbaseConnector.#instance); } protected onChainChanged(hexChainId: string): void { const chainId = parseInt(hexChainId, 16).toString(); - this.emit("chainChanged", chainId, CoinbaseConnector.#instance); + this.emitter.emit("chainChanged", chainId, CoinbaseConnector.#instance); } protected onDisconnect(error: any): void { console.error({ error, }); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/injected.ts b/packages/evm/src/connectors/injected.ts index add5d32..79fb156 100644 --- a/packages/evm/src/connectors/injected.ts +++ b/packages/evm/src/connectors/injected.ts @@ -21,11 +21,7 @@ export class InjectedConnector extends BaseConnector { super("injected", "ethereum"); } - static getInstance() { - return this.#instance; - } - - init() { + static init() { if (!InjectedConnector.#instance) { InjectedConnector.#instance = new InjectedConnector() as BaseConnector; @@ -121,7 +117,7 @@ export class InjectedConnector extends BaseConnector { await this.provider.send("wallet_addEthereumChain", [options]); } - this.emit( + this.emitter.emit( "switchingChain", oldChainId, chainId, @@ -165,7 +161,7 @@ export class InjectedConnector extends BaseConnector { const address = await this.getAccount(); - this.emit( + this.emitter.emit( "connected", address[0]!, currentId, @@ -194,7 +190,7 @@ export class InjectedConnector extends BaseConnector { if (!this.provider) await this.getProvider(); try { await this.provider.destroy(); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); return { walletName: this.name, ecosystem: this.ecosystem, @@ -226,7 +222,7 @@ export class InjectedConnector extends BaseConnector { throw new UserRejectedRequestError(); } - this.emit( + this.emitter.emit( "messageSigned", response as string, InjectedConnector.#instance @@ -246,18 +242,18 @@ export class InjectedConnector extends BaseConnector { } protected onAccountsChanged(accounts: string[]): void { - this.emit("accountsChanged", accounts, InjectedConnector.#instance); + this.emitter.emit("accountsChanged", accounts, InjectedConnector.#instance); } protected onChainChanged(hexChainId: string): void { const chainId = parseInt(hexChainId, 16).toString(); - this.emit("chainChanged", chainId, InjectedConnector.#instance); + this.emitter.emit("chainChanged", chainId, InjectedConnector.#instance); } protected onDisconnect(error: any): void { console.error({ error, }); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/okxwallet.ts b/packages/evm/src/connectors/okxwallet.ts index f4a1b0b..b67644e 100644 --- a/packages/evm/src/connectors/okxwallet.ts +++ b/packages/evm/src/connectors/okxwallet.ts @@ -27,11 +27,7 @@ export class OkxWalletConnector extends BaseConnector { super("okxwallet", "ethereum"); } - static getInstance() { - return this.#instance; - } - - init() { + static init() { if (!OkxWalletConnector.#instance) { OkxWalletConnector.#instance = new OkxWalletConnector() as BaseConnector; @@ -124,7 +120,7 @@ export class OkxWalletConnector extends BaseConnector { await this.provider.send("wallet_addEthereumChain", [options]); } - this.emit( + this.emitter.emit( "switchingChain", oldChainId, chainId, @@ -168,7 +164,7 @@ export class OkxWalletConnector extends BaseConnector { const address = await this.getAccount(); - this.emit( + this.emitter.emit( "connected", address[0]!, await this.getChainId(), @@ -197,7 +193,7 @@ export class OkxWalletConnector extends BaseConnector { if (!this.provider) await this.getProvider(); try { await this.provider.destroy(); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); return { walletName: this.name, ecosystem: this.ecosystem, @@ -229,7 +225,7 @@ export class OkxWalletConnector extends BaseConnector { throw new UserRejectedRequestError(); } - this.emit( + this.emitter.emit( "messageSigned", response as string, OkxWalletConnector.#instance @@ -249,18 +245,22 @@ export class OkxWalletConnector extends BaseConnector { } protected onAccountsChanged(accounts: string[]): void { - this.emit("accountsChanged", accounts, OkxWalletConnector.#instance); + this.emitter.emit( + "accountsChanged", + accounts, + OkxWalletConnector.#instance + ); } protected onChainChanged(hexChainId: string): void { const chainId = parseInt(hexChainId, 16).toString(); - this.emit("chainChanged", chainId, OkxWalletConnector.#instance); + this.emitter.emit("chainChanged", chainId, OkxWalletConnector.#instance); } protected onDisconnect(error: any): void { console.error({ error, }); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/evm/src/connectors/walletconnect.ts b/packages/evm/src/connectors/walletconnect.ts index ee2088e..94466dd 100644 --- a/packages/evm/src/connectors/walletconnect.ts +++ b/packages/evm/src/connectors/walletconnect.ts @@ -20,9 +20,7 @@ import { DisconnectionResponse, } from "@wallet01/core/dist/types/methodTypes"; -type WalletconnectConnectorOptions = { - chain?: string; -} & EthereumProviderOptions; +type WalletconnectConnectorOptions = EthereumProviderOptions; const NAMESPACE = "eip155"; const ADD_ETH_CHAIN_METHOD = "wallet_addEthereumChain"; @@ -32,13 +30,9 @@ export class WalletconnectConnector extends BaseConnector { provider!: EthereumProvider; static options: EthereumProviderOptions; - constructor({ - chain = "1", - chains, - projectId, - ...params - }: WalletconnectConnectorOptions) { + constructor({ chains, projectId, ...params }: WalletconnectConnectorOptions) { super("walletconnect", "ethereum"); + console.log(this.emitter); WalletconnectConnector.options = { chains, projectId, @@ -49,15 +43,10 @@ export class WalletconnectConnector extends BaseConnector { }; } - static getInstance(options: WalletconnectConnectorOptions) { - WalletconnectConnector.options = options; - return this.#instance; - } - - init() { + static init(options: WalletconnectConnectorOptions) { if (!WalletconnectConnector.#instance) { WalletconnectConnector.#instance = new WalletconnectConnector( - WalletconnectConnector.options + options ) as BaseConnector; } return WalletconnectConnector.#instance; @@ -147,7 +136,7 @@ export class WalletconnectConnector extends BaseConnector { params: [{ chainId: hexChainId }], }); - this.emit( + this.emitter.emit( "switchingChain", oldChainId, chainId, @@ -196,9 +185,17 @@ export class WalletconnectConnector extends BaseConnector { this.provider.on("disconnect", this.onDisconnect); this.provider.on("accountsChanged", this.onAccountsChanged); - this.provider.on("chainChanged", this.onChainChanged); + this.provider.on("chainChanged", hexChainId => { + const chainId = parseInt(hexChainId, 16).toString(); + + this.emitter.emit( + "chainChanged", + chainId, + WalletconnectConnector.#instance + ); + }); - this.emit( + this.emitter.emit( "connected", accounts[0]!, currentChainId, @@ -226,7 +223,7 @@ export class WalletconnectConnector extends BaseConnector { throw new ProviderNotFoundError({ walletName: this.name }); await this.provider.disconnect(); - this.emit("disconnected", this.name, "ethereum"); + this.emitter.emit("disconnected", this.name, "ethereum"); return { walletName: this.name, ecosystem: "ethereum", @@ -258,7 +255,7 @@ export class WalletconnectConnector extends BaseConnector { throw new UserRejectedRequestError(); } - this.emit( + this.emitter.emit( "messageSigned", response as string, WalletconnectConnector.#instance @@ -308,18 +305,26 @@ export class WalletconnectConnector extends BaseConnector { } protected onAccountsChanged(accounts: string[]): void { - this.emit("accountsChanged", accounts, WalletconnectConnector.#instance); + this.emitter.emit( + "accountsChanged", + accounts, + WalletconnectConnector.#instance + ); } protected onChainChanged(hexChainId: string): void { const chainId = parseInt(hexChainId, 16).toString(); - this.emit("chainChanged", chainId, WalletconnectConnector.#instance); + this.emitter.emit( + "chainChanged", + chainId, + WalletconnectConnector.#instance + ); } protected onDisconnect(error: any): void { console.error({ error, }); - this.emit("disconnected", this.name, this.ecosystem); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/react/src/context.tsx b/packages/react/src/context.tsx index cf8cab4..224411c 100644 --- a/packages/react/src/context.tsx +++ b/packages/react/src/context.tsx @@ -28,6 +28,8 @@ const Wallet01: FunctionComponent = ({ connectors: typeof connectors === "function" ? connectors() : connectors, }); + console.log("setting client"); + setWalletClient(client); }, [connectors]); diff --git a/packages/react/src/hooks/useAccount.ts b/packages/react/src/hooks/useAccount.ts index c9802b5..4aaa38f 100644 --- a/packages/react/src/hooks/useAccount.ts +++ b/packages/react/src/hooks/useAccount.ts @@ -10,17 +10,14 @@ type useAccountConfig = { ) => Promise | void; }; -export const userAccount = ({}: useAccountConfig) => { +export const userAccount = ({ onAccountChange }: useAccountConfig) => { const client = useContext(ClientProvider); const { address, addresses, activeConnector } = useStore(); useEffect(() => { if (!client) throw new ClientNotFoundError(); - // if (onAccountChange) - // client.on("accountsChanged", (address, activeConnector) => - // onAccountChange(address, activeConnector) - // ); + if (onAccountChange) client.emitter.on("accountsChanged", onAccountChange); }, [activeConnector, client]); return { diff --git a/packages/react/src/hooks/useChain.ts b/packages/react/src/hooks/useChain.ts new file mode 100644 index 0000000..8130045 --- /dev/null +++ b/packages/react/src/hooks/useChain.ts @@ -0,0 +1,24 @@ +import { BaseConnector, useStore } from "@wallet01/core"; +import { useContext, useEffect } from "react"; +import { ClientProvider } from "../context"; +import { ClientNotFoundError } from "../utils/errors"; + +interface useChainConfig { + onChainChanged?: (chainId: string, activeConnector: BaseConnector) => void; +} + +export const useChain = ({ onChainChanged }: useChainConfig) => { + const client = useContext(ClientProvider); + const { activeConnector, chainId } = useStore(); + + useEffect(() => { + if (!client) throw new ClientNotFoundError(); + + if (onChainChanged) client.emitter.on("chainChanged", onChainChanged); + }, [activeConnector, client]); + + return { + chainId, + activeConnector, + }; +}; diff --git a/packages/react/src/hooks/useConnect.ts b/packages/react/src/hooks/useConnect.ts index 7c1fd37..24ef4d5 100644 --- a/packages/react/src/hooks/useConnect.ts +++ b/packages/react/src/hooks/useConnect.ts @@ -4,6 +4,7 @@ import { useCallback, useContext } from "react"; import { ClientProvider } from "../context"; import { ClientNotFoundError, ConnectorNotFoundError } from "../utils/errors"; import { ConnectionResponse } from "@wallet01/core/dist/types/methodTypes"; +import { TEcosystem } from "@wallet01/core/dist/store/storeTypes"; type ConnectArgs = { connector: BaseConnector; @@ -11,14 +12,20 @@ type ConnectArgs = { }; type UseConenctConfig = { - onError?: UseMutationOptions["onError"]; - onConnect?: (params: ConnectionResponse) => Promise | void; + onError?: UseMutationOptions["onError"]; + onConnect?: ( + address: string, + chainId: string, + walletName: string, + ecosystem: TEcosystem, + activeConnector: BaseConnector + ) => Promise | void; }; export const useConnect = ({ onError, -} // onConnect, -: Partial = {}) => { + onConnect, +}: Partial = {}) => { const client = useContext(ClientProvider); const { mutate, mutateAsync, isLoading, isError, error } = useMutation< @@ -28,39 +35,23 @@ export const useConnect = ({ unknown >({ mutationFn: async ({ connector, chainId }: ConnectArgs) => { - try { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError(); - const connectors = client.store.getConnectors(); + const connectors = client.store.getConnectors(); - if (!connectors.includes(connector)) - throw new ConnectorNotFoundError({ connectorName: connector.name }); + if (!connectors.includes(connector)) + throw new ConnectorNotFoundError({ connectorName: connector.name }); - let connectionResult: ConnectionResponse; + let connectionResult: ConnectionResponse; - if (chainId) { - connectionResult = await connector.connect({ chainId: chainId }); - } else { - connectionResult = await connector.connect(); - } - - // if (onConnect) - // client.on( - // "connected", - // (address, chainId, walletName, ecosystem, activeConnector) => - // onConnect({ - // activeConnector, - // address, - // chainId, - // ecosystem, - // walletName, - // }) - // ); - - return connectionResult; - } catch (error) { - throw error; + if (onConnect) client.emitter.on("connected", onConnect); + if (chainId) { + connectionResult = await connector.connect({ chainId: chainId }); + } else { + connectionResult = await connector.connect(); } + + return connectionResult; }, onError, }); diff --git a/packages/react/src/hooks/useDisconnect.ts b/packages/react/src/hooks/useDisconnect.ts new file mode 100644 index 0000000..4ab529c --- /dev/null +++ b/packages/react/src/hooks/useDisconnect.ts @@ -0,0 +1,57 @@ +import { UseMutationOptions, useMutation } from "@tanstack/react-query"; +import { DisconnectionResponse } from "@wallet01/core/dist/types/methodTypes"; +import { ClientProvider } from "../context"; +import { useCallback, useContext } from "react"; +import { ClientNotFoundError, NoWalletConnectedError } from "../utils/errors"; +import { TEcosystem } from "@wallet01/core/dist/store/storeTypes"; + +interface useDisconnectConfig { + onError?: UseMutationOptions["onError"]; + onDisconnect?: (walletName: string, ecosystem: TEcosystem) => void; +} + +export const useDisconnect = ({ + onDisconnect, + onError, +}: useDisconnectConfig) => { + const client = useContext(ClientProvider); + + const { data, isLoading, isError, mutate, mutateAsync, error } = useMutation< + DisconnectionResponse, + Error, + void, + unknown + >({ + mutationFn: async () => { + if (!client) throw new ClientNotFoundError(); + + const activeConnector = client.store.getActiveConnector(); + + if (!activeConnector) + throw new NoWalletConnectedError({ methodName: "disconnect" }); + const response = await activeConnector.disconnect(); + + if (onDisconnect) client.emitter.on("disconnected", onDisconnect); + + return response; + }, + onError, + }); + + const disconnect = useCallback(() => { + return mutate(); + }, [client]); + + const disconnectAsync = useCallback(() => { + return mutateAsync(); + }, [client]); + + return { + disconnect, + disconnectAsync, + disconnectionResponse: data, + isLoading, + isError, + error, + }; +}; diff --git a/packages/react/src/hooks/useMessage.ts b/packages/react/src/hooks/useMessage.ts index 1c03cf9..cb96e8f 100644 --- a/packages/react/src/hooks/useMessage.ts +++ b/packages/react/src/hooks/useMessage.ts @@ -2,17 +2,25 @@ import { UseMutationOptions, useMutation } from "@tanstack/react-query"; import { useCallback, useContext } from "react"; import { ClientProvider } from "../context"; import { ClientNotFoundError, NoWalletConnectedError } from "../utils/errors"; -import { MessageSignedResponse } from "@wallet01/core/dist/types/methodTypes"; +import { + MessageSignedResponse, + SignatureHash, +} from "@wallet01/core/dist/types/methodTypes"; +import { BaseConnector } from "@wallet01/core"; interface SignMessageArgs { message: string; } interface useMessageConfig { - onError?: UseMutationOptions["onError"]; - onMessageSigned?: ({ - activeConnector, - signature, - }: MessageSignedResponse) => void; + onError?: UseMutationOptions< + MessageSignedResponse, + Error, + SignMessageArgs + >["onError"]; + onMessageSigned?: ( + signature: SignatureHash, + activeConnector: BaseConnector + ) => void; } /** * @description This hooks will return signMessage function that helps sign messages from desired wallet. @@ -22,7 +30,7 @@ interface useMessageConfig { * For more details visit {@link} */ -export const useMessage = ({ onError }: useMessageConfig) => { +export const useMessage = ({ onError, onMessageSigned }: useMessageConfig) => { const client = useContext(ClientProvider); const { data, isLoading, isError, mutate, mutateAsync, error } = useMutation< @@ -32,25 +40,18 @@ export const useMessage = ({ onError }: useMessageConfig) => { unknown >({ mutationFn: async ({ message }: SignMessageArgs) => { - try { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError(); - const activeConnector = client.store.getActiveConnector(); + const activeConnector = client.store.getActiveConnector(); - if (!activeConnector) - throw new NoWalletConnectedError({ methodName: "signMessage" }); + if (!activeConnector) + throw new NoWalletConnectedError({ methodName: "signMessage" }); - const response = await activeConnector.signMessage(message); + if (onMessageSigned) client.emitter.on("messageSigned", onMessageSigned); - // if (onMessageSigned) - // client.on("messageSigned", (signature, activeConnector) => - // onMessageSigned({ signature, activeConnector }) - // ); + const response = await activeConnector.signMessage(message); - return response; - } catch (error) { - throw error; - } + return response; }, onError, }); diff --git a/packages/react/src/hooks/useSwitch.ts b/packages/react/src/hooks/useSwitch.ts index 860d527..3fa1cbb 100644 --- a/packages/react/src/hooks/useSwitch.ts +++ b/packages/react/src/hooks/useSwitch.ts @@ -7,14 +7,19 @@ import { NoWalletConnectedError, UnsupportedFunctionCalledError, } from "../utils/errors"; +import { BaseConnector } from "@wallet01/core"; interface ChainSwitchArgs { chainId: string; } interface useMessageConfig { - onError?: UseMutationOptions["onError"]; - onChainSwitched?: (params: ChainSwitchResponse) => void; + onError?: UseMutationOptions["onError"]; + onChainSwitched?: ( + fromChainId: string | "mainnet", + toChainId: string | "mainnet", + activeConnector: BaseConnector + ) => void; } /** @@ -25,7 +30,7 @@ interface useMessageConfig { * For more details visit {@link} */ -export const useSwitch = ({ onError }: useMessageConfig) => { +export const useSwitch = ({ onError, onChainSwitched }: useMessageConfig) => { const client = useContext(ClientProvider); const { isLoading, isError, error, mutate, mutateAsync } = useMutation< @@ -54,12 +59,8 @@ export const useSwitch = ({ onError }: useMessageConfig) => { walletName: activeConnector.name, }); - // if (onChainSwitched) - // client.on( - // "switchingChain", - // (fromChainId, toChainId, activeConnector) => - // onChainSwitched({ fromChainId, toChainId, activeConnector }) - // ); + if (onChainSwitched) + client.emitter.on("switchingChain", onChainSwitched); const response = await activeConnector.switchChain(chainId); diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index 529c8d0..a326692 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -9,5 +9,5 @@ export default defineConfig({ skipNodeModulesBundle: true, target: "es2020", outDir: "dist", - entry: ["src/*index.ts"], //include all files under src + entry: ["src/index.ts"], //include all files under src }); From 9c9014ff19de0999631f3d64bdb6edf034fcb952 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Wed, 11 Oct 2023 14:31:27 +0530 Subject: [PATCH 06/17] fix: hooks params; nextjs build --- examples/nextjs/components/ConnectedModal.tsx | 22 ++-- examples/nextjs/lib/filecoin.ts | 111 ------------------ examples/nextjs/package.json | 3 - packages/react/src/hooks/index.ts | 14 ++- packages/react/src/hooks/useAccount.ts | 5 +- packages/react/src/hooks/useChain.ts | 5 +- packages/react/src/hooks/useConnect.ts | 9 +- packages/react/src/hooks/useDisconnect.ts | 10 +- packages/react/src/hooks/useMessage.ts | 7 +- packages/react/src/hooks/useSwitch.ts | 42 +++---- packages/react/src/index.ts | 10 +- pnpm-lock.yaml | 63 +++++----- 12 files changed, 92 insertions(+), 209 deletions(-) delete mode 100644 examples/nextjs/lib/filecoin.ts diff --git a/examples/nextjs/components/ConnectedModal.tsx b/examples/nextjs/components/ConnectedModal.tsx index 9325f4f..c590723 100644 --- a/examples/nextjs/components/ConnectedModal.tsx +++ b/examples/nextjs/components/ConnectedModal.tsx @@ -1,14 +1,20 @@ -import { useClient, useMessage, useSwitch, useWallet } from "@wallet01/react"; +import { + useClient, + useDisconnect, + useMessage, + useSwitch, + useWallet, +} from "@wallet01/react"; import React, { useState } from "react"; import WalletIcons from "./assets/WalletIcons"; -import { BeaconConnector } from "@wallet01/tezos"; const ConnectedModal = () => { const [message, setMessage] = useState(""); const [chainId, setChainId] = useState(""); const { activeConnector, address, chainId: cId } = useWallet(); - const { signMessage, hash } = useMessage({}); - const { switchChain } = useSwitch({}); + const { signMessage, hash } = useMessage(); + const { disconnect } = useDisconnect(); + const { switchChain } = useSwitch(); const { ecosystem } = useClient(); return ( @@ -36,15 +42,15 @@ const ConnectedModal = () => { {cId} } - {activeConnector?.name === "beacon" ? ( + {/* {activeConnector?.name === "beacon" ? ( {BeaconConnector.publicKey} - ) : null} - {/* */} +
diff --git a/examples/nextjs/lib/filecoin.ts b/examples/nextjs/lib/filecoin.ts deleted file mode 100644 index fa48e9e..0000000 --- a/examples/nextjs/lib/filecoin.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { ethers } from "ethers"; -import { hexValue } from "ethers/lib/utils"; -import { Web3Provider, ExternalProvider } from "@ethersproject/providers"; -import detectEthereumProvider from "@metamask/detect-provider"; - -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; - -export class FilecoinConnector extends BaseConnector { - provider?: Web3Provider; - - constructor(chain: string = "3141") { - super(chain, "filecoin", "ethereum"); - this.getProvider(); - } - - async getProvider() { - const provider = await detectEthereumProvider(); - - if (provider) { - const _provider = new ethers.providers.Web3Provider( - (provider) - ); - this.provider = _provider; - return this.provider; - } else { - throw new Error("Please install a Browser Wallet"); - } - } - - async getAccount(): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("No Provider Found!"); - const result = await this.provider.send("eth_requestAccounts", []); - return result; - } catch (err) { - console.error(err); - throw new Error("Error in getting Accounts"); - } - } - - async getChainId(): Promise { - if (this.provider) { - const { result } = await this.provider?.send("eth_chainId", []); - return result; - } - return ""; - } - - async switchChain(chainId: string): Promise { - const provider = await this.getProvider(); - - const id = hexValue(Number(chainId)); - try { - await provider?.send("wallet_switchEthereumChain", [{ chainId: id }]); - } catch (error) { - console.error("error in switching chain", error); - throw error; - } - } - - async connect({ chainId = "3141" }) { - try { - const provider = await this.getProvider(); - this.provider = provider; - - if (provider.on) { - provider.on("accountsChanged", this.onAccountsChanged); - provider.on("chainChanged", this.onChainChanged); - provider.on("disconnect", this.onDisconnect); - } - - let id = await this.getChainId(); - - if (chainId && id !== chainId) { - await this.switchChain(chainId); - } - setLastUsedConnector(this.name); - } catch (error) { - console.error(error, "in connect"); - throw error; - } - } - - async disconnect(): Promise { - this.provider = undefined; - } - - async resolveDid(address: string): Promise { - return null; - } - - async signMessage(message: string): Promise { - if (!this.provider) throw new Error("Connect a wallet!"); - const signer = await this.provider.getSigner(); - const hash = await signer.signMessage(message); - return hash; - } - - protected onAccountsChanged(): void { - console.log("Account Changed"); - } - - protected onChainChanged(_chain: string): void { - console.log("Chain Changed"); - } - - protected onDisconnect(): void { - console.log("Wallet disconnected"); - } -} diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index f222253..f8de6cc 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -12,11 +12,8 @@ "@ethersproject/providers": "^5.7.2", "@metamask/detect-provider": "^2.0.0", "@wallet01/core": "workspace:*", - "@wallet01/cosmos": "workspace:*", "@wallet01/evm": "workspace:*", "@wallet01/react": "workspace:*", - "@wallet01/solana": "workspace:*", - "@wallet01/tezos": "workspace:*", "ethers": "^5.7.2", "next": "13.0.3", "react": "18.2.0", diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 696d87f..011be57 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -3,5 +3,17 @@ import { useMessage } from "./useMessage"; import { useSwitch } from "./useSwitch"; import { useClient } from "./useClient"; import { useWallet } from "./useWallet"; +import { useDisconnect } from "./useDisconnect"; +import { useChain } from "./useChain"; +import { userAccount } from "./useAccount"; -export { useConnect, useMessage, useSwitch, useClient, useWallet }; +export { + useConnect, + useMessage, + useSwitch, + useClient, + useWallet, + useDisconnect, + useChain, + userAccount, +}; diff --git a/packages/react/src/hooks/useAccount.ts b/packages/react/src/hooks/useAccount.ts index 4aaa38f..370dd94 100644 --- a/packages/react/src/hooks/useAccount.ts +++ b/packages/react/src/hooks/useAccount.ts @@ -10,14 +10,15 @@ type useAccountConfig = { ) => Promise | void; }; -export const userAccount = ({ onAccountChange }: useAccountConfig) => { +export const userAccount = (params?: useAccountConfig) => { const client = useContext(ClientProvider); const { address, addresses, activeConnector } = useStore(); useEffect(() => { if (!client) throw new ClientNotFoundError(); - if (onAccountChange) client.emitter.on("accountsChanged", onAccountChange); + if (params?.onAccountChange) + client.emitter.on("accountsChanged", params.onAccountChange); }, [activeConnector, client]); return { diff --git a/packages/react/src/hooks/useChain.ts b/packages/react/src/hooks/useChain.ts index 8130045..cedc564 100644 --- a/packages/react/src/hooks/useChain.ts +++ b/packages/react/src/hooks/useChain.ts @@ -7,14 +7,15 @@ interface useChainConfig { onChainChanged?: (chainId: string, activeConnector: BaseConnector) => void; } -export const useChain = ({ onChainChanged }: useChainConfig) => { +export const useChain = (params?: useChainConfig) => { const client = useContext(ClientProvider); const { activeConnector, chainId } = useStore(); useEffect(() => { if (!client) throw new ClientNotFoundError(); - if (onChainChanged) client.emitter.on("chainChanged", onChainChanged); + if (params?.onChainChanged) + client.emitter.on("chainChanged", params.onChainChanged); }, [activeConnector, client]); return { diff --git a/packages/react/src/hooks/useConnect.ts b/packages/react/src/hooks/useConnect.ts index 24ef4d5..52ccd6e 100644 --- a/packages/react/src/hooks/useConnect.ts +++ b/packages/react/src/hooks/useConnect.ts @@ -22,10 +22,7 @@ type UseConenctConfig = { ) => Promise | void; }; -export const useConnect = ({ - onError, - onConnect, -}: Partial = {}) => { +export const useConnect = (params?: UseConenctConfig) => { const client = useContext(ClientProvider); const { mutate, mutateAsync, isLoading, isError, error } = useMutation< @@ -44,7 +41,7 @@ export const useConnect = ({ let connectionResult: ConnectionResponse; - if (onConnect) client.emitter.on("connected", onConnect); + if (params?.onConnect) client.emitter.on("connected", params.onConnect); if (chainId) { connectionResult = await connector.connect({ chainId: chainId }); } else { @@ -53,7 +50,7 @@ export const useConnect = ({ return connectionResult; }, - onError, + onError: params?.onError, }); const connect = useCallback( diff --git a/packages/react/src/hooks/useDisconnect.ts b/packages/react/src/hooks/useDisconnect.ts index 4ab529c..306ac97 100644 --- a/packages/react/src/hooks/useDisconnect.ts +++ b/packages/react/src/hooks/useDisconnect.ts @@ -10,10 +10,7 @@ interface useDisconnectConfig { onDisconnect?: (walletName: string, ecosystem: TEcosystem) => void; } -export const useDisconnect = ({ - onDisconnect, - onError, -}: useDisconnectConfig) => { +export const useDisconnect = (params?: useDisconnectConfig) => { const client = useContext(ClientProvider); const { data, isLoading, isError, mutate, mutateAsync, error } = useMutation< @@ -31,11 +28,12 @@ export const useDisconnect = ({ throw new NoWalletConnectedError({ methodName: "disconnect" }); const response = await activeConnector.disconnect(); - if (onDisconnect) client.emitter.on("disconnected", onDisconnect); + if (params?.onDisconnect) + client.emitter.on("disconnected", params.onDisconnect); return response; }, - onError, + onError: params?.onError, }); const disconnect = useCallback(() => { diff --git a/packages/react/src/hooks/useMessage.ts b/packages/react/src/hooks/useMessage.ts index cb96e8f..685386e 100644 --- a/packages/react/src/hooks/useMessage.ts +++ b/packages/react/src/hooks/useMessage.ts @@ -30,7 +30,7 @@ interface useMessageConfig { * For more details visit {@link} */ -export const useMessage = ({ onError, onMessageSigned }: useMessageConfig) => { +export const useMessage = (params?: useMessageConfig) => { const client = useContext(ClientProvider); const { data, isLoading, isError, mutate, mutateAsync, error } = useMutation< @@ -47,13 +47,14 @@ export const useMessage = ({ onError, onMessageSigned }: useMessageConfig) => { if (!activeConnector) throw new NoWalletConnectedError({ methodName: "signMessage" }); - if (onMessageSigned) client.emitter.on("messageSigned", onMessageSigned); + if (params?.onMessageSigned) + client.emitter.on("messageSigned", params.onMessageSigned); const response = await activeConnector.signMessage(message); return response; }, - onError, + onError: params?.onError, }); const signMessage = useCallback( diff --git a/packages/react/src/hooks/useSwitch.ts b/packages/react/src/hooks/useSwitch.ts index 3fa1cbb..7d245ff 100644 --- a/packages/react/src/hooks/useSwitch.ts +++ b/packages/react/src/hooks/useSwitch.ts @@ -30,7 +30,7 @@ interface useMessageConfig { * For more details visit {@link} */ -export const useSwitch = ({ onError, onChainSwitched }: useMessageConfig) => { +export const useSwitch = (params?: useMessageConfig) => { const client = useContext(ClientProvider); const { isLoading, isError, error, mutate, mutateAsync } = useMutation< @@ -40,36 +40,32 @@ export const useSwitch = ({ onError, onChainSwitched }: useMessageConfig) => { unknown >({ mutationFn: async ({ chainId }: ChainSwitchArgs) => { - try { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError(); - const activeConnector = client.store.getActiveConnector(); - const connectors = client.store.getConnectors(); + const activeConnector = client.store.getActiveConnector(); + const connectors = client.store.getConnectors(); - if (!activeConnector) - throw new NoWalletConnectedError({ methodName: "switchChain" }); + if (!activeConnector) + throw new NoWalletConnectedError({ methodName: "switchChain" }); - if (!connectors.includes(activeConnector)) { - throw new Error("Connector not found"); - } + if (!connectors.includes(activeConnector)) { + throw new Error("Connector not found"); + } - if (!activeConnector.switchChain) - throw new UnsupportedFunctionCalledError({ - methodName: "switchChain", - walletName: activeConnector.name, - }); + if (!activeConnector.switchChain) + throw new UnsupportedFunctionCalledError({ + methodName: "switchChain", + walletName: activeConnector.name, + }); - if (onChainSwitched) - client.emitter.on("switchingChain", onChainSwitched); + if (params?.onChainSwitched) + client.emitter.on("switchingChain", params.onChainSwitched); - const response = await activeConnector.switchChain(chainId); + const response = await activeConnector.switchChain(chainId); - return response; - } catch (error) { - throw error; - } + return response; }, - onError, + onError: params?.onError, }); const switchChain = useCallback( diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index fc402fe..15eb54d 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,10 +1,4 @@ -import { - useClient, - useConnect, - useMessage, - useSwitch, - useWallet, -} from "./hooks"; import Wallet01 from "./context"; +export * from "./hooks"; -export { Wallet01, useClient, useConnect, useMessage, useSwitch, useWallet }; +export { Wallet01 }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c7d42a..dacba7f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 3.0.3 turbo: specifier: latest - version: 1.10.14 + version: 1.10.15 configs/eslint: dependencies: @@ -31,7 +31,7 @@ importers: version: 8.5.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.14(eslint@7.32.0) + version: 1.10.15(eslint@7.32.0) devDependencies: typescript: specifier: ^4.7.4 @@ -50,21 +50,12 @@ importers: '@wallet01/core': specifier: workspace:* version: link:../../packages/core - '@wallet01/cosmos': - specifier: workspace:* - version: link:../../packages/cosmos '@wallet01/evm': specifier: workspace:* version: link:../../packages/evm '@wallet01/react': specifier: workspace:* version: link:../../packages/react - '@wallet01/solana': - specifier: workspace:* - version: link:../../packages/solana - '@wallet01/tezos': - specifier: workspace:* - version: link:../../packages/tezos ethers: specifier: ^5.7.2 version: 5.7.2 @@ -4242,13 +4233,13 @@ packages: eslint: 7.32.0 dev: false - /eslint-config-turbo@1.10.14(eslint@7.32.0): - resolution: {integrity: sha512-ZeB+IcuFXy1OICkLuAplVa0euoYbhK+bMEQd0nH9+Lns18lgZRm33mVz/iSoH9VdUzl/1ZmFmoK+RpZc+8R80A==} + /eslint-config-turbo@1.10.15(eslint@7.32.0): + resolution: {integrity: sha512-76mpx2x818JZE26euen14utYcFDxOahZ9NaWA+6Xa4pY2ezVKVschuOxS96EQz3o3ZRSmcgBOapw/gHbN+EKxQ==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.10.14(eslint@7.32.0) + eslint-plugin-turbo: 1.10.15(eslint@7.32.0) dev: false /eslint-import-resolver-node@0.3.6: @@ -4394,8 +4385,8 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-turbo@1.10.14(eslint@7.32.0): - resolution: {integrity: sha512-sBdBDnYr9AjT1g4lR3PBkZDonTrMnR4TvuGv5W0OiF7z9az1rI68yj2UHJZvjkwwcGu5mazWA1AfB0oaagpmfg==} + /eslint-plugin-turbo@1.10.15(eslint@7.32.0): + resolution: {integrity: sha512-Tv4QSKV/U56qGcTqS/UgOvb9HcKFmWOQcVh3HEaj7of94lfaENgfrtK48E2CckQf7amhKs1i+imhCsNCKjkQyA==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -7303,64 +7294,64 @@ packages: yargs: 17.6.2 dev: true - /turbo-darwin-64@1.10.14: - resolution: {integrity: sha512-I8RtFk1b9UILAExPdG/XRgGQz95nmXPE7OiGb6ytjtNIR5/UZBS/xVX/7HYpCdmfriKdVwBKhalCoV4oDvAGEg==} + /turbo-darwin-64@1.10.15: + resolution: {integrity: sha512-Sik5uogjkRTe1XVP9TC2GryEMOJCaKE2pM/O9uLn4koQDnWKGcLQv+mDU+H+9DXvKLnJnKCD18OVRkwK5tdpoA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.14: - resolution: {integrity: sha512-KAdUWryJi/XX7OD0alOuOa0aJ5TLyd4DNIYkHPHYcM6/d7YAovYvxRNwmx9iv6Vx6IkzTnLeTiUB8zy69QkG9Q==} + /turbo-darwin-arm64@1.10.15: + resolution: {integrity: sha512-xwqyFDYUcl2xwXyGPmHkmgnNm4Cy0oNzMpMOBGRr5x64SErS7QQLR4VHb0ubiR+VAb8M+ECPklU6vD1Gm+wekg==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.14: - resolution: {integrity: sha512-BOBzoREC2u4Vgpap/WDxM6wETVqVMRcM8OZw4hWzqCj2bqbQ6L0wxs1LCLWVrghQf93JBQtIGAdFFLyCSBXjWQ==} + /turbo-linux-64@1.10.15: + resolution: {integrity: sha512-dM07SiO3RMAJ09Z+uB2LNUSkPp3I1IMF8goH5eLj+d8Kkwoxd/+qbUZOj9RvInyxU/IhlnO9w3PGd3Hp14m/nA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.14: - resolution: {integrity: sha512-D8T6XxoTdN5D4V5qE2VZG+/lbZX/89BkAEHzXcsSUTRjrwfMepT3d2z8aT6hxv4yu8EDdooZq/2Bn/vjMI32xw==} + /turbo-linux-arm64@1.10.15: + resolution: {integrity: sha512-MkzKLkKYKyrz4lwfjNXH8aTny5+Hmiu4SFBZbx+5C0vOlyp6fV5jZANDBvLXWiDDL4DSEAuCEK/2cmN6FVH1ow==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.14: - resolution: {integrity: sha512-zKNS3c1w4i6432N0cexZ20r/aIhV62g69opUn82FLVs/zk3Ie0GVkSB6h0rqIvMalCp7enIR87LkPSDGz9K4UA==} + /turbo-windows-64@1.10.15: + resolution: {integrity: sha512-3TdVU+WEH9ThvQGwV3ieX/XHebtYNHv9HARHauPwmVj3kakoALkpGxLclkHFBLdLKkqDvmHmXtcsfs6cXXRHJg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.14: - resolution: {integrity: sha512-rkBwrTPTxNSOUF7of8eVvvM+BkfkhA2OvpHM94if8tVsU+khrjglilp8MTVPHlyS9byfemPAmFN90oRIPB05BA==} + /turbo-windows-arm64@1.10.15: + resolution: {integrity: sha512-l+7UOBCbfadvPMYsX08hyLD+UIoAkg6ojfH+E8aud3gcA1padpjCJTh9gMpm3QdMbKwZteT5uUM+wyi6Rbbyww==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.14: - resolution: {integrity: sha512-hr9wDNYcsee+vLkCDIm8qTtwhJ6+UAMJc3nIY6+PNgUTtXcQgHxCq8BGoL7gbABvNWv76CNbK5qL4Lp9G3ZYRA==} + /turbo@1.10.15: + resolution: {integrity: sha512-mKKkqsuDAQy1wCCIjCdG+jOCwUflhckDMSRoeBPcIL/CnCl7c5yRDFe7SyaXloUUkt4tUR0rvNIhVCcT7YeQpg==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.10.14 - turbo-darwin-arm64: 1.10.14 - turbo-linux-64: 1.10.14 - turbo-linux-arm64: 1.10.14 - turbo-windows-64: 1.10.14 - turbo-windows-arm64: 1.10.14 + turbo-darwin-64: 1.10.15 + turbo-darwin-arm64: 1.10.15 + turbo-linux-64: 1.10.15 + turbo-linux-arm64: 1.10.15 + turbo-windows-64: 1.10.15 + turbo-windows-arm64: 1.10.15 dev: true /tweetnacl@1.0.3: From 8cb4273d8f06c5b7f063a9ea46a9761e7823b6b4 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 14:48:12 +0530 Subject: [PATCH 07/17] feat: updated the cosmos package and added chainSwitch event listener in client --- examples/nextjs/package.json | 1 + examples/nextjs/pages/_app.tsx | 4 +- packages/core/src/client/client.ts | 10 + packages/core/src/utils/errors.ts | 42 ++++ packages/cosmos/package.json | 2 +- packages/cosmos/src/connectors/keplr.ts | 191 ++++++++++++---- packages/cosmos/src/types/chainConfig.ts | 9 - packages/cosmos/src/types/index.ts | 15 -- packages/cosmos/src/utils/emiter.ts | 12 - packages/cosmos/src/utils/errors.ts | 6 + packages/solana/package.json | 1 - pnpm-lock.yaml | 277 +---------------------- 12 files changed, 210 insertions(+), 360 deletions(-) delete mode 100644 packages/cosmos/src/types/chainConfig.ts delete mode 100644 packages/cosmos/src/types/index.ts delete mode 100644 packages/cosmos/src/utils/emiter.ts create mode 100644 packages/cosmos/src/utils/errors.ts diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index f8de6cc..ea993b5 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -14,6 +14,7 @@ "@wallet01/core": "workspace:*", "@wallet01/evm": "workspace:*", "@wallet01/react": "workspace:*", + "@wallet01/cosmos": "workspace:*", "ethers": "^5.7.2", "next": "13.0.3", "react": "18.2.0", diff --git a/examples/nextjs/pages/_app.tsx b/examples/nextjs/pages/_app.tsx index d469604..e33e0ac 100644 --- a/examples/nextjs/pages/_app.tsx +++ b/examples/nextjs/pages/_app.tsx @@ -9,7 +9,7 @@ import { BananaConnector, OkxWalletConnector, } from "@wallet01/evm"; -// import { KeplrConnector } from "@wallet01/cosmos"; +import { KeplrConnector } from "@wallet01/cosmos"; // import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; // import { BeaconConnector, TempleConnector } from "@wallet01/tezos"; import Layout from "../components/layout"; @@ -38,7 +38,7 @@ export default function App({ Component, pageProps }: AppProps) { // new SolflareConnector({ // rpcUrl: "https://api.mainnet-beta.solana.com", // }), - // new KeplrConnector(), + KeplrConnector.init("osmosis"), // new TempleConnector({ projectName: "Wallet01" }), // new BeaconConnector({ // name: "Wallet01", diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index 6c7e4ed..acca2f1 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -68,6 +68,16 @@ export default class Wallet01Client { this.store.setIsConnected(false); }); + this.emitter.on( + "switchingChain", + async (_f, toChainId, activeConnector) => { + const accounts = await activeConnector.getAccount(); + if (accounts[0]) this.store.setAddress(accounts[0]); + this.store.setActiveConnector(activeConnector); + this.store.setChainId(toChainId); + } + ); + this.emitter.on("chainChanged", chainId => { this.store.setChainId(chainId); }); diff --git a/packages/core/src/utils/errors.ts b/packages/core/src/utils/errors.ts index d0c6094..e75599d 100644 --- a/packages/core/src/utils/errors.ts +++ b/packages/core/src/utils/errors.ts @@ -55,3 +55,45 @@ export class UserRejectedRequestError extends Error { super(`User rejected the request.`); } } + +export class UnsupportedChainError extends Error { + name = "UnsupportedChainError"; + chainId: string; + + constructor({ chainId }: { chainId: string }) { + super(`ChainId: ${chainId} is not supported`); + this.chainId = chainId; + } +} + +export class WalletCreationError extends Error { + name = "WalletCreationError"; + + constructor({ walletName }: { walletName: string }) { + super(`Error while creating ${walletName} wallet.`); + } +} + +export class MessageSignError extends Error { + name = "MessageSignError"; + + constructor({ walletName }: { walletName: string }) { + super(`Error while signing message with ${walletName} wallet.`); + } +} + +export class UnrecognisedChainError extends Error { + name = "UnrecognisedChainError"; + + constructor({ + walletName, + chainId, + }: { + walletName: string; + chainId: string; + }) { + super( + `Unrecognised chainId ${chainId} provided. Please provide options to add chain to ${walletName} wallet.` + ); + } +} diff --git a/packages/cosmos/package.json b/packages/cosmos/package.json index 41a88d1..4908d04 100644 --- a/packages/cosmos/package.json +++ b/packages/cosmos/package.json @@ -12,7 +12,7 @@ }, "license": "MIT", "dependencies": { - "@keplr-wallet/types": "^0.11.13", + "@keplr-wallet/types": "^0.12.32", "@wallet01/core": "workspace:*", "eventemitter3": "^4.0.7" }, diff --git a/packages/cosmos/src/connectors/keplr.ts b/packages/cosmos/src/connectors/keplr.ts index 8a284e7..2d3618b 100644 --- a/packages/cosmos/src/connectors/keplr.ts +++ b/packages/cosmos/src/connectors/keplr.ts @@ -1,35 +1,69 @@ import { Window as KeplrWindow } from "@keplr-wallet/types"; import { KeplrProvider } from "../providers/keplrProvider"; -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; -import emitter from "../utils/emiter"; +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, +} from "@wallet01/core"; +import { AddressNotFoundError } from "../utils/errors"; +import { + ChainSwitchResponse, + ConnectionResponse, + MessageSignedResponse, +} from "@wallet01/core/dist/types/methodTypes"; declare const window: KeplrWindow; export class KeplrConnector extends BaseConnector { + static #instance: BaseConnector; provider!: KeplrProvider; + private chain = "secret-4"; - constructor(chain: string = "secret-4") { - super(chain, "keplr", "cosmos"); + private constructor(chainId?: string) { + super("keplr", "cosmos"); + if (chainId) this.chain = chainId; } - async getProvider(): Promise { - if (typeof window !== "undefined" && window.keplr) { - this.provider = window.keplr; - return this.provider; - } else { - throw new Error("Wallet Not Installed!"); + static init(chainId?: string) { + if (!KeplrConnector.#instance) { + KeplrConnector.#instance = new KeplrConnector( + chainId + ) as BaseConnector; } + return KeplrConnector.#instance; } - async getAccount(): Promise { - if (!this.provider) throw new Error("Provider undefined"); + async getProvider() { try { + if (typeof window !== "undefined" && window.keplr) { + this.provider = window.keplr; + return this.provider; + } + throw new ProviderNotFoundError({ walletName: this.name }); + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); + } + } + + async getAccount() { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + await this.provider.enable(this.chain); const { bech32Address } = await this.provider.getKey(this.chain); return [bech32Address]; } catch (error) { console.error({ error }); - throw new Error("Error in getting accounts"); + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } @@ -37,69 +71,126 @@ export class KeplrConnector extends BaseConnector { return this.chain; } - async switchChain(chainId: string): Promise { - if (!this.provider) throw new Error("Provider undefined"); + async switchChain(chainId: string): Promise { + if (!this.provider) await this.getProvider(); try { - await this.provider.enable(chainId); - this.chain = chainId; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const fromChainId = await this.getChainId(); + + const toChainId = chainId; + + await this.provider.disable(); + + await this.provider.enable(toChainId); + this.chain = toChainId; + + this.emitter.emit( + "switchingChain", + fromChainId, + toChainId, + KeplrConnector.#instance + ); + + return { + fromChainId, + toChainId, + activeConnector: KeplrConnector.#instance, + }; } catch (err) { console.error(err); throw err; } } - async connect({ chainId = "secret-4" }): Promise { + async connect( + options?: { chainId: string } | undefined + ): Promise { + if (!this.provider) await this.getProvider(); try { - const provider = await this.getProvider(); - if (!provider) throw new Error("Keplr not installed"); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); - await this.provider.enable(chainId); - this.chain = chainId; - setLastUsedConnector(this.name); + if (options?.chainId) { + await this.switchChain(options.chainId); + this.chain = options.chainId; + } else { + await this.provider.enable(this.chain); + } + + const { bech32Address } = await this.provider.getKey(this.chain); + + this.emitter.emit( + "connected", + bech32Address, + this.chain, + this.name, + this.ecosystem, + KeplrConnector.#instance + ); + + return { + activeConnector: KeplrConnector.#instance, + address: bech32Address, + chainId: this.chain, + ecosystem: this.ecosystem, + walletName: this.name, + }; } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "connect", + }); } } - async disconnect(): Promise { - this.chain = ""; - emitter.emit("disconnected"); - } - - async resolveDid(_address: string): Promise { - console.error("Cosmos Ecosystem doesn't support DIDs as of now"); - throw new Error("Cosmos Ecosystem doesn't support DIDs as of now"); + async disconnect() { + if (!this.provider) await this.getProvider(); + try { + await this.provider.disable(); + this.emitter.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); + } } - async signMessage(message: string): Promise { - if (!this.provider) throw new Error("Provider Undefined"); + async signMessage(message: string): Promise { + if (!this.provider) await this.getProvider(); try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); const address = (await this.getAccount())[0]; - if (!address) throw new Error("No address found"); + if (!address) throw new AddressNotFoundError({ walletName: this.name }); const { signature } = await this.provider.signArbitrary( this.chain, address, message ); - return signature; - } catch (error) { - console.warn(error); - throw error; - } - } - - protected onAccountsChanged(): void { - console.log("Account Changed"); - } - protected onChainChanged(_chain: string | number): void { - console.log("Chain Changed"); - } + this.emitter.emit("messageSigned", signature, KeplrConnector.#instance); - protected onDisconnect(): void { - console.log("Wallet disconnected"); + return { + signature, + activeConnector: KeplrConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); + } } } diff --git a/packages/cosmos/src/types/chainConfig.ts b/packages/cosmos/src/types/chainConfig.ts deleted file mode 100644 index f91530f..0000000 --- a/packages/cosmos/src/types/chainConfig.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type CustomChainConfig = { - chainNamespace: 'eip155' | 'solana' | 'other'; - chainId: string; - rpcTarget?: string; - displayName: string; - blockExplorer?: string; - ticker: string; - tickerName: string; -}; diff --git a/packages/cosmos/src/types/index.ts b/packages/cosmos/src/types/index.ts deleted file mode 100644 index a2ef279..0000000 --- a/packages/cosmos/src/types/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { BaseConnector } from '@wallet01/core'; -import { CustomChainConfig } from './chainConfig'; - -type ClientConfig = { - chainConfig: CustomChainConfig; - connector: BaseConnector; -}; - -type ConnectedData = { - account: string; - chainId: string; - provider: TProvider; -}; - -export { type CustomChainConfig, type ClientConfig, type ConnectedData }; diff --git a/packages/cosmos/src/utils/emiter.ts b/packages/cosmos/src/utils/emiter.ts deleted file mode 100644 index 17c4b4b..0000000 --- a/packages/cosmos/src/utils/emiter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import EventEmitter from 'eventemitter3'; - -const eventEmitter = new EventEmitter(); -const emitter = { - on: (event: string, fn: (args: any) => void) => eventEmitter.on(event, fn), - once: (event: string, fn: () => void) => eventEmitter.once(event, fn), - off: (event: string, fn: () => void) => eventEmitter.off(event, fn), - emit: (event: string, payload?: unknown) => eventEmitter.emit(event, payload), -}; - -Object.freeze(emitter); -export default emitter; diff --git a/packages/cosmos/src/utils/errors.ts b/packages/cosmos/src/utils/errors.ts new file mode 100644 index 0000000..f36ba57 --- /dev/null +++ b/packages/cosmos/src/utils/errors.ts @@ -0,0 +1,6 @@ +export class AddressNotFoundError extends Error { + name = "AddressNotFoundError"; + constructor({ walletName }: { walletName: string }) { + super(`Address not found in ${walletName} wallet.`); + } +} diff --git a/packages/solana/package.json b/packages/solana/package.json index 936e395..2ed4a98 100644 --- a/packages/solana/package.json +++ b/packages/solana/package.json @@ -13,7 +13,6 @@ }, "dependencies": { "@bonfida/spl-name-service": "^0.1.55", - "@keplr-wallet/types": "^0.11.13", "@solana/web3.js": "^1.66.2", "@wallet01/core": "workspace:*", "eventemitter3": "^4.0.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dacba7f..073bfc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ importers: '@wallet01/core': specifier: workspace:* version: link:../../packages/core + '@wallet01/cosmos': + specifier: workspace:* + version: link:../../packages/cosmos '@wallet01/evm': specifier: workspace:* version: link:../../packages/evm @@ -177,8 +180,8 @@ importers: packages/cosmos: dependencies: '@keplr-wallet/types': - specifier: ^0.11.13 - version: 0.11.17 + specifier: ^0.12.32 + version: 0.12.32 '@wallet01/core': specifier: workspace:* version: link:../core @@ -284,9 +287,6 @@ importers: '@bonfida/spl-name-service': specifier: ^0.1.55 version: 0.1.55(@solana/spl-token@0.1.8)(@solana/web3.js@1.66.2)(bn.js@5.2.1)(borsh@0.6.0) - '@keplr-wallet/types': - specifier: ^0.11.13 - version: 0.11.17 '@solana/web3.js': specifier: ^1.66.2 version: 1.66.2 @@ -1411,35 +1411,6 @@ packages: /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - /@iov/crypto@2.1.0: - resolution: {integrity: sha512-jnb4XuK50admolm7fBxOcxfAW2TO+wYrZlhDWiMETItY/Y5gNNa1zaDSO2wNIjjfGng+8nQ1yqnNhqy7busV2Q==} - dependencies: - '@iov/encoding': 2.1.0 - bip39: 3.0.4 - bn.js: 4.12.0 - elliptic: 6.5.4 - js-sha3: 0.8.0 - libsodium-wrappers: 0.7.10 - pbkdf2: 3.1.2 - ripemd160: 2.0.2 - sha.js: 2.4.11 - type-tagger: 1.0.0 - unorm: 1.6.0 - dev: false - - /@iov/encoding@2.1.0: - resolution: {integrity: sha512-5IOdLO7Xg/uRykuiCqeMYghQ3IjWDtGxv7NTWXkgpHuna0aewx43mRpT2NPCpOZd1tpuorDtQ7/zbDNRaIIF/w==} - dependencies: - base64-js: 1.5.1 - bech32: 1.1.4 - bn.js: 4.12.0 - readonly-date: 1.0.0 - dev: false - - /@iov/utils@2.0.2: - resolution: {integrity: sha512-4D8MEvTcFc/DVy5q25vHxRItmgJyeX85dixMH+MxdKr+yy71h3sYk+sVBEIn70uqGP7VqAJkGOPNFs08/XYELw==} - dev: false - /@jridgewell/gen-mapping@0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} engines: {node: '>=6.0.0'} @@ -1478,14 +1449,10 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@keplr-wallet/types@0.11.17: - resolution: {integrity: sha512-ks3+L8SR4Wnn/kqafpJB2g/wzgNVoW3Y48Qb8vddnWmgub/ib1g1Xs3RB7lRzvrgWsuj2xmNCK9BFLcdisW6+g==} + /@keplr-wallet/types@0.12.32: + resolution: {integrity: sha512-uxTz2Tidmob12dy0Hp+posGkm9WFW5sFSpVenIX6geRIfJwgpApDWZ1oD4NtRPy8s5aa51DirJceSuIYz+fx1g==} dependencies: - axios: 0.27.2 long: 4.0.0 - secretjs: 0.17.7 - transitivePeerDependencies: - - debug dev: false /@lit-labs/ssr-dom-shim@1.1.1: @@ -1772,49 +1739,6 @@ packages: resolution: {integrity: sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==} dev: false - /@protobufjs/aspromise@1.1.2: - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: false - - /@protobufjs/base64@1.1.2: - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: false - - /@protobufjs/codegen@2.0.4: - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: false - - /@protobufjs/eventemitter@1.1.0: - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: false - - /@protobufjs/fetch@1.1.0: - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - dev: false - - /@protobufjs/float@1.0.2: - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: false - - /@protobufjs/inquire@1.1.0: - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: false - - /@protobufjs/path@1.1.2: - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: false - - /@protobufjs/pool@1.1.0: - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: false - - /@protobufjs/utf8@1.1.0: - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: false - /@rize-labs/banana-wallet-sdk@0.1.18: resolution: {integrity: sha512-zV4pwjfaefMoQ8ZUsRv2QhhB0Xs3Q7JlcnBCYBBASHNtAqINH3eBO9d2ZLaTvNuAc0jzWBhLsOx2tQwR2ReoWw==} dependencies: @@ -2349,10 +2273,6 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/long@4.0.2: - resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} - dev: false - /@types/minimist@1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true @@ -2361,10 +2281,6 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: false - /@types/node@11.11.6: - resolution: {integrity: sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==} - dev: false - /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -3149,14 +3065,6 @@ packages: engines: {node: '>=4'} dev: true - /axios@0.21.1: - resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==} - dependencies: - follow-redirects: 1.15.2 - transitivePeerDependencies: - - debug - dev: false - /axios@0.24.0: resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} dependencies: @@ -3181,15 +3089,6 @@ packages: - debug dev: false - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - /axios@1.3.6: resolution: {integrity: sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==} dependencies: @@ -3255,15 +3154,6 @@ packages: file-uri-to-path: 1.0.0 dev: false - /bip39@3.0.4: - resolution: {integrity: sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==} - dependencies: - '@types/node': 11.11.6 - create-hash: 1.2.0 - pbkdf2: 3.1.2 - randombytes: 2.1.0 - dev: false - /blakejs@1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} dev: false @@ -3397,13 +3287,6 @@ packages: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: false - /buffer@5.4.3: - resolution: {integrity: sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: false - /buffer@6.0.1: resolution: {integrity: sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==} dependencies: @@ -3491,10 +3374,6 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /charenc@0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - dev: false - /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -3649,10 +3528,6 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /crypt@0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - dev: false - /crypto-browserify@3.12.0: resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} dependencies: @@ -3699,10 +3574,6 @@ packages: stream-transform: 2.1.3 dev: true - /curve25519-js@0.0.4: - resolution: {integrity: sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==} - dev: false - /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -4722,10 +4593,6 @@ packages: engines: {node: '> 0.1.90'} dev: false - /fast-deep-equal@3.1.1: - resolution: {integrity: sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==} - dev: false - /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -5189,10 +5056,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -5364,46 +5227,6 @@ packages: engines: {node: '>=10'} dev: true - /js-crypto-env@0.3.2: - resolution: {integrity: sha512-F1uHiCkSOo36qBuuZABA4sBf+xeFBzhJZ0Sd7af8FAruszIhm1Xxv+Zr5Ne90Zlh7/fnxCsrdkj0N8f0a3lVlQ==} - dev: false - - /js-crypto-hash@0.6.3: - resolution: {integrity: sha512-SG8c9tM8y3sUb4k7WvpVfu5vU7zfPvX+eaYR5578TvehkehdaQbqAc+y+1FwxnqQ3WZ0gsYoOKp/mW+mqtNoWA==} - dependencies: - buffer: 5.4.3 - hash.js: 1.1.7 - js-crypto-env: 0.3.2 - md5: 2.2.1 - sha3: 2.1.4 - dev: false - - /js-crypto-hkdf@0.7.3: - resolution: {integrity: sha512-eAaVArAjS2GCacWGXY4hjBiexrLQYlI0PMOcbwtrSEj84XU3kUfMYZm9bpTyaTXgdHC/eQoXe/Of6biG+RSEaQ==} - dependencies: - js-crypto-env: 0.3.2 - js-crypto-hmac: 0.6.3 - js-crypto-random: 0.4.3 - js-encoding-utils: 0.5.6 - dev: false - - /js-crypto-hmac@0.6.3: - resolution: {integrity: sha512-T0pKOaHACOSG6Xs6/06G8RDDeZouQwIQNBq9L/zoUGsd4F67gAjpT3q2lGigAGpUd1hiyy7vnhvLpz7VDt6DbA==} - dependencies: - js-crypto-env: 0.3.2 - js-crypto-hash: 0.6.3 - dev: false - - /js-crypto-random@0.4.3: - resolution: {integrity: sha512-C3gzphPPfw9jfQ9Q/LjhJMZxQNp3AaoVRDvyZkiB+zYltfs8tKQPsskWkXACpg1Nzh01PtSRUvVijjptd2qGHQ==} - dependencies: - js-crypto-env: 0.3.2 - dev: false - - /js-encoding-utils@0.5.6: - resolution: {integrity: sha512-qnAGsUIWrmzh5n+3AXqbxX1KsB9hkQmJZf3aA9DLAS7GpL/NEHCBreFFbW+imramoU+Q0TDyvkwhRbBRH1TVkg==} - dev: false - /js-sdsl@4.2.0: resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} dev: true @@ -5533,16 +5356,6 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 - /libsodium-wrappers@0.7.10: - resolution: {integrity: sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==} - dependencies: - libsodium: 0.7.10 - dev: false - - /libsodium@0.7.10: - resolution: {integrity: sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==} - dev: false - /lilconfig@2.0.6: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} @@ -5680,14 +5493,6 @@ packages: safe-buffer: 5.2.1 dev: false - /md5@2.2.1: - resolution: {integrity: sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==} - dependencies: - charenc: 0.0.2 - crypt: 0.0.2 - is-buffer: 1.1.6 - dev: false - /meow@6.1.1: resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} engines: {node: '>=8'} @@ -5777,10 +5582,6 @@ packages: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} dev: true - /miscreant@0.3.2: - resolution: {integrity: sha512-fL9KxsQz9BJB2KGPMHFrReioywkiomBiuaLk6EuChijK0BsJsIKJXdVomR+/bPj5mvbFD6wM0CM3bZio9g7OHA==} - dev: false - /mixme@0.5.4: resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} engines: {node: '>= 8.0.0'} @@ -6072,10 +5873,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - /pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: false - /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -6332,25 +6129,6 @@ packages: react-is: 16.13.1 dev: true - /protobufjs@6.11.3: - resolution: {integrity: sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==} - requiresBuild: true - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/long': 4.0.2 - '@types/node': 18.11.18 - long: 4.0.0 - dev: false - /proxy-compare@2.5.0: resolution: {integrity: sha512-f1us0OsVAJ3tdIMXGQx2lmseYS4YXe4W+sKF5g5ww/jV+5ogMadPt+sIZ+88Ga9kvMJsrRNWzCrKPpr6pMWYbA==} dev: false @@ -6558,10 +6336,6 @@ packages: picomatch: 2.3.1 dev: true - /readonly-date@1.0.0: - resolution: {integrity: sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==} - dev: false - /real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} @@ -6724,28 +6498,6 @@ packages: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} dev: false - /secretjs@0.17.7: - resolution: {integrity: sha512-j39l9+vR2A8067QBqDDejS7LmRLgdkG4uRw2Ar6HMfzDGo26eTh7cIXVlVu/yHBumxtQzKun20epOXwuYHXjQg==} - dependencies: - '@iov/crypto': 2.1.0 - '@iov/encoding': 2.1.0 - '@iov/utils': 2.0.2 - axios: 0.21.1 - curve25519-js: 0.0.4 - fast-deep-equal: 3.1.1 - js-crypto-hkdf: 0.7.3 - miscreant: 0.3.2 - pako: 1.0.11 - protobufjs: 6.11.3 - secure-random: 1.1.2 - transitivePeerDependencies: - - debug - dev: false - - /secure-random@1.1.2: - resolution: {integrity: sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ==} - dev: false - /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} dev: true @@ -6775,12 +6527,6 @@ packages: safe-buffer: 5.2.1 dev: false - /sha3@2.1.4: - resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} - dependencies: - buffer: 6.0.3 - dev: false - /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -7383,10 +7129,6 @@ packages: engines: {node: '>=8'} dev: true - /type-tagger@1.0.0: - resolution: {integrity: sha512-FIPqqpmDgdaulCnRoKv1/d3U4xVBUrYn42QXWNP3XYmgfPUDuBUsgFOb9ntT0aIe0UsUP+lknpQ5d9Kn36RssA==} - dev: false - /typedarray-to-buffer@4.0.0: resolution: {integrity: sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==} dev: false @@ -7431,11 +7173,6 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /unorm@1.6.0: - resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} - engines: {node: '>= 0.4.0'} - dev: false - /update-browserslist-db@1.0.10(browserslist@4.21.4): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} hasBin: true From 5fdab74940e4d85b46e34aa115d3e11f06e1adbf Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 15:11:50 +0530 Subject: [PATCH 08/17] fix: ethers errors in injected connectors --- packages/core/src/client/client.ts | 2 +- packages/core/src/client/store.ts | 2 +- .../core/src/utils/EnhancedEventEmitter.ts | 2 +- packages/evm/package.json | 2 +- packages/evm/src/connectors/banana.ts | 10 ++-- packages/evm/src/connectors/coinbase.ts | 8 +-- packages/evm/src/connectors/injected.ts | 53 ++++++++++------- packages/evm/src/connectors/okxwallet.ts | 27 +++++---- packages/evm/src/connectors/walletconnect.ts | 10 +++- packages/evm/src/utils/errors.ts | 41 ------------- pnpm-lock.yaml | 57 +------------------ 11 files changed, 71 insertions(+), 143 deletions(-) delete mode 100644 packages/evm/src/utils/errors.ts diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index acca2f1..e54548d 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -9,7 +9,7 @@ export default class Wallet01Client { public store: Wallet01Store = Wallet01Store.init(); - constructor({ autoConnect = false, connectors }: ClientConfig) { + private constructor({ autoConnect = false, connectors }: ClientConfig) { this.emitter = EnhancedEventEmitter.init(); this.store.setConnectors(connectors); diff --git a/packages/core/src/client/store.ts b/packages/core/src/client/store.ts index 3489648..b0199d7 100644 --- a/packages/core/src/client/store.ts +++ b/packages/core/src/client/store.ts @@ -5,7 +5,7 @@ import { BaseConnector } from "../types"; export class Wallet01Store { static #instance: Wallet01Store; - constructor() { + private constructor() { this.getState = getState; } diff --git a/packages/core/src/utils/EnhancedEventEmitter.ts b/packages/core/src/utils/EnhancedEventEmitter.ts index 9fb12ca..e23735e 100644 --- a/packages/core/src/utils/EnhancedEventEmitter.ts +++ b/packages/core/src/utils/EnhancedEventEmitter.ts @@ -7,7 +7,7 @@ class EnhancedEventEmitter { static #instance: EnhancedEventEmitter; private emitter: EventEmitter; - constructor() { + private constructor() { this.emitter = new EventEmitter(); this.emitter.setMaxListeners(Infinity); } diff --git a/packages/evm/package.json b/packages/evm/package.json index bb856eb..37a00eb 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -21,7 +21,7 @@ "@walletconnect/modal": "^2.5.2", "@web3modal/core": "^2.2.2", "@web3modal/standalone": "^2.2.2", - "ethers": "^6.7.1", + "ethers": "^5.7.2", "eventemitter3": "^4.0.7" }, "devDependencies": { diff --git a/packages/evm/src/connectors/banana.ts b/packages/evm/src/connectors/banana.ts index 5025c01..ca66ebc 100644 --- a/packages/evm/src/connectors/banana.ts +++ b/packages/evm/src/connectors/banana.ts @@ -1,8 +1,11 @@ import { BaseConnector, + MessageSignError, ProviderNotFoundError, UnknownError, + UnsupportedChainError, WalletConnectionError, + WalletCreationError, WalletNotConnectedError, } from "@wallet01/core"; import { @@ -12,11 +15,6 @@ import { Chains, } from "@rize-labs/banana-wallet-sdk"; import { isBananSupported, getBananaSupportedChain } from "../utils/helpers"; -import { - MessageSignError, - UnsupportedChainError, - WalletCreationError, -} from "../utils/errors"; export class BananaConnector extends BaseConnector { static #instance: BaseConnector; @@ -25,7 +23,7 @@ export class BananaConnector extends BaseConnector { private BananaInstance!: Banana; private wallet!: Wallet; - constructor() { + private constructor() { super("banana", "ethereum"); } diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index cb1e3af..4f22b12 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -2,13 +2,13 @@ import { BaseConnector, ProviderNotFoundError, UnknownError, + UnrecognisedChainError, UserRejectedRequestError, } from "@wallet01/core"; import { CoinbaseWalletProvider } from "@coinbase/wallet-sdk"; import { CoinbaseWalletSDK } from "@coinbase/wallet-sdk"; -import { hexlify, toUtf8Bytes, toQuantity } from "ethers"; +import { hexlify, toUtf8Bytes, hexValue } from "ethers/lib/utils.js"; import { CoinbaseWalletSDKOptions } from "@coinbase/wallet-sdk/dist/CoinbaseWalletSDK"; -import { UnrecognisedChainError } from "../utils/errors"; import { AddChainParameter, ConnectionResponse, @@ -21,7 +21,7 @@ export class CoinbaseConnector extends BaseConnector< static options: CoinbaseWalletSDKOptions; provider!: CoinbaseWalletProvider; - constructor(options: CoinbaseWalletSDKOptions) { + private constructor(options: CoinbaseWalletSDKOptions) { super("coinbase", "ethereum"); CoinbaseConnector.options = options; } @@ -97,7 +97,7 @@ export class CoinbaseConnector extends BaseConnector< throw new ProviderNotFoundError({ walletName: this.name }); const oldChainId = await this.getChainId(); - const hexChainId = toQuantity(Number(chainId)); + const hexChainId = hexValue(Number(chainId)); const params = [{ chainId: hexChainId }]; const response = await this.provider.request({ diff --git a/packages/evm/src/connectors/injected.ts b/packages/evm/src/connectors/injected.ts index 79fb156..89ea46e 100644 --- a/packages/evm/src/connectors/injected.ts +++ b/packages/evm/src/connectors/injected.ts @@ -1,30 +1,32 @@ -import { toQuantity, BrowserProvider, hexlify, toUtf8Bytes } from "ethers"; +import { hexValue, toUtf8Bytes, hexlify } from "ethers/lib/utils.js"; +import { Web3Provider } from "@ethersproject/providers"; import { BaseConnector, ProviderNotFoundError, UnknownError, + UnrecognisedChainError, UserRejectedRequestError, } from "@wallet01/core"; -import { UnrecognisedChainError } from "../utils/errors"; import { AddChainParameter, ChainSwitchResponse, } from "@wallet01/core/dist/types/methodTypes"; +import { ProviderRpcError } from "@walletconnect/ethereum-provider/dist/types/types"; -export class InjectedConnector extends BaseConnector { - static #instance: BaseConnector; - provider!: BrowserProvider; +export class InjectedConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: Web3Provider; - constructor() { + private constructor() { super("injected", "ethereum"); } static init() { if (!InjectedConnector.#instance) { InjectedConnector.#instance = - new InjectedConnector() as BaseConnector; + new InjectedConnector() as BaseConnector; } return InjectedConnector.#instance; } @@ -38,7 +40,7 @@ export class InjectedConnector extends BaseConnector { if (!windowProvider) throw new ProviderNotFoundError({ walletName: this.name }); - const provider = new BrowserProvider(windowProvider); + const provider = new Web3Provider(windowProvider); this.provider = provider; return this.provider; @@ -101,20 +103,25 @@ export class InjectedConnector extends BaseConnector { throw new ProviderNotFoundError({ walletName: this.name }); const oldChainId = await this.getChainId(); - const hexChainId = toQuantity(Number(chainId)); + const hexChainId = hexValue(Number(chainId)); const params = [{ chainId: hexChainId }]; - const response = await this.provider.send( - "wallet_switchEthereumChain", - params - ); - - if ((response as any).code === 4902) { - if (!options) { - throw new UnrecognisedChainError({ walletName: this.name, chainId }); + try { + await this.provider.send("wallet_switchEthereumChain", params); + } catch (error) { + if ( + (error as ProviderRpcError).code && + (error as ProviderRpcError).code === 4902 + ) { + if (!options) { + throw new UnrecognisedChainError({ + walletName: this.name, + chainId, + }); + } + + await this.provider.send("wallet_addEthereumChain", [options]); } - - await this.provider.send("wallet_addEthereumChain", [options]); } this.emitter.emit( @@ -189,7 +196,13 @@ export class InjectedConnector extends BaseConnector { async disconnect() { if (!this.provider) await this.getProvider(); try { - await this.provider.destroy(); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + this.provider.removeListener("accountsChanged", this.onAccountsChanged); + this.provider.removeListener("chainChanged", this.onChainChanged); + this.provider.removeListener("disconnect", this.onDisconnect); + this.emitter.emit("disconnected", this.name, this.ecosystem); return { walletName: this.name, diff --git a/packages/evm/src/connectors/okxwallet.ts b/packages/evm/src/connectors/okxwallet.ts index b67644e..55a384d 100644 --- a/packages/evm/src/connectors/okxwallet.ts +++ b/packages/evm/src/connectors/okxwallet.ts @@ -1,9 +1,11 @@ -import { toQuantity, BrowserProvider, hexlify, toUtf8Bytes } from "ethers"; +import { hexValue, toUtf8Bytes, hexlify } from "ethers/lib/utils.js"; +import { Web3Provider } from "@ethersproject/providers"; import { BaseConnector, ProviderNotFoundError, UnknownError, + UnrecognisedChainError, UserRejectedRequestError, } from "@wallet01/core"; @@ -11,7 +13,6 @@ import { AddChainParameter, ChainSwitchResponse, } from "@wallet01/core/dist/types/methodTypes"; -import { UnrecognisedChainError } from "../utils/errors"; interface OkxWalletWindow extends Window { okxwallet?: any; @@ -19,18 +20,18 @@ interface OkxWalletWindow extends Window { declare const window: OkxWalletWindow; -export class OkxWalletConnector extends BaseConnector { - static #instance: BaseConnector; - provider!: BrowserProvider; +export class OkxWalletConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: Web3Provider; - constructor() { + private constructor() { super("okxwallet", "ethereum"); } static init() { if (!OkxWalletConnector.#instance) { OkxWalletConnector.#instance = - new OkxWalletConnector() as BaseConnector; + new OkxWalletConnector() as BaseConnector; } return OkxWalletConnector.#instance; } @@ -42,7 +43,7 @@ export class OkxWalletConnector extends BaseConnector { if (!windowProvider) throw new ProviderNotFoundError({ walletName: this.name }); - const provider = new BrowserProvider(windowProvider); + const provider = new Web3Provider(windowProvider); this.provider = provider; return this.provider; } catch (error) { @@ -104,7 +105,7 @@ export class OkxWalletConnector extends BaseConnector { throw new ProviderNotFoundError({ walletName: this.name }); const oldChainId = await this.getChainId(); - const hexChainId = toQuantity(Number(chainId)); + const hexChainId = hexValue(Number(chainId)); const params = [{ chainId: hexChainId }]; const response = await this.provider.send( @@ -192,7 +193,13 @@ export class OkxWalletConnector extends BaseConnector { async disconnect() { if (!this.provider) await this.getProvider(); try { - await this.provider.destroy(); + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + this.provider.removeListener("accountsChanged", this.onAccountsChanged); + this.provider.removeListener("chainChanged", this.onChainChanged); + this.provider.removeListener("disconnect", this.onDisconnect); + this.emitter.emit("disconnected", this.name, this.ecosystem); return { walletName: this.name, diff --git a/packages/evm/src/connectors/walletconnect.ts b/packages/evm/src/connectors/walletconnect.ts index 94466dd..1188dae 100644 --- a/packages/evm/src/connectors/walletconnect.ts +++ b/packages/evm/src/connectors/walletconnect.ts @@ -1,4 +1,4 @@ -import { hexlify, toQuantity, toUtf8Bytes } from "ethers"; +import { hexlify, hexValue, toUtf8Bytes } from "ethers/lib/utils.js"; import { BaseConnector, @@ -30,7 +30,11 @@ export class WalletconnectConnector extends BaseConnector { provider!: EthereumProvider; static options: EthereumProviderOptions; - constructor({ chains, projectId, ...params }: WalletconnectConnectorOptions) { + private constructor({ + chains, + projectId, + ...params + }: WalletconnectConnectorOptions) { super("walletconnect", "ethereum"); console.log(this.emitter); WalletconnectConnector.options = { @@ -111,7 +115,7 @@ export class WalletconnectConnector extends BaseConnector { throw new ProviderNotFoundError({ walletName: this.name }); const oldChainId = await this.getChainId(); - const hexChainId = toQuantity(Number(chainId)); + const hexChainId = hexValue(Number(chainId)); const namespaceChains = this.getNamespaceChainsIds(); const namespaceMethods = this.getNamespaceMethods(); const isChainApproved = namespaceChains.includes(chainId); diff --git a/packages/evm/src/utils/errors.ts b/packages/evm/src/utils/errors.ts deleted file mode 100644 index e8c0271..0000000 --- a/packages/evm/src/utils/errors.ts +++ /dev/null @@ -1,41 +0,0 @@ -export class UnsupportedChainError extends Error { - name = "UnsupportedChainError"; - chainId: string; - - constructor({ chainId }: { chainId: string }) { - super(`ChainId: ${chainId} is not supported`); - this.chainId = chainId; - } -} - -export class WalletCreationError extends Error { - name = "WalletCreationError"; - - constructor({ walletName }: { walletName: string }) { - super(`Error while creating ${walletName} wallet.`); - } -} - -export class MessageSignError extends Error { - name = "MessageSignError"; - - constructor({ walletName }: { walletName: string }) { - super(`Error while signing message with ${walletName} wallet.`); - } -} - -export class UnrecognisedChainError extends Error { - name = "UnrecognisedChainError"; - - constructor({ - walletName, - chainId, - }: { - walletName: string; - chainId: string; - }) { - super( - `Unrecognised chainId ${chainId} provided. Please provide options to add chain to ${walletName} wallet.` - ); - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 073bfc0..d1f1a89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -232,8 +232,8 @@ importers: specifier: ^2.2.2 version: 2.2.2 ethers: - specifier: ^6.7.1 - version: 6.7.1 + specifier: ^5.7.2 + version: 5.7.2 eventemitter3: specifier: ^4.0.7 version: 4.0.7 @@ -384,10 +384,6 @@ packages: - utf-8-validate dev: false - /@adraffy/ens-normalize@1.9.2: - resolution: {integrity: sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==} - dev: false - /@airgap/beacon-core@4.0.2: resolution: {integrity: sha512-a6mAn6BfbejBQI95tRc6pIZ0VS6MTK9MZ7iXPTLF9hrnCHiROmrCgNKst8qp2dcE0Ehk7z/hGs2WliJzi657YA==} dependencies: @@ -1698,10 +1694,6 @@ packages: resolution: {integrity: sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==} dev: false - /@noble/hashes@1.1.2: - resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} - dev: false - /@noble/hashes@1.1.3: resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} dev: false @@ -1710,10 +1702,6 @@ packages: resolution: {integrity: sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==} dev: false - /@noble/secp256k1@1.7.1: - resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} - dev: false - /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2291,10 +2279,6 @@ packages: resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} dev: true - /@types/node@18.15.13: - resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} - dev: false - /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -2870,10 +2854,6 @@ packages: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} dev: false - /aes-js@4.0.0-beta.5: - resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} - dev: false - /agentkeepalive@4.2.1: resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} engines: {node: '>= 8.0.0'} @@ -4528,22 +4508,6 @@ packages: - utf-8-validate dev: false - /ethers@6.7.1: - resolution: {integrity: sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==} - engines: {node: '>=14.0.0'} - dependencies: - '@adraffy/ens-normalize': 1.9.2 - '@noble/hashes': 1.1.2 - '@noble/secp256k1': 1.7.1 - '@types/node': 18.15.13 - aes-js: 4.0.0-beta.5 - tslib: 2.4.0 - ws: 8.5.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false @@ -6937,10 +6901,6 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - /tslib@2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - dev: false - /tslib@2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} dev: false @@ -7436,19 +7396,6 @@ packages: utf-8-validate: 5.0.10 dev: false - /ws@8.5.0: - resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} From 91057f3eb2636e88f7b075a2c03aaa87fb8fd5a9 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 16:21:37 +0530 Subject: [PATCH 09/17] feat: updated the solana package according to the new arch --- examples/nextjs/package.json | 1 + examples/nextjs/pages/_app.tsx | 10 +- packages/core/src/utils/errors.ts | 15 + packages/evm/package.json | 1 - packages/solana/package.json | 7 +- packages/solana/src/connectors/phantom.ts | 174 ++++++----- packages/solana/src/connectors/solflare.ts | 178 ++++++----- packages/solana/src/index.ts | 8 +- .../solana/src/providers/phantomProvider.ts | 50 ++-- .../solana/src/providers/solflareProvider.ts | 15 - packages/solana/src/types/chainConfig.ts | 9 - packages/solana/src/types/index.ts | 15 - packages/solana/src/utils/emiter.ts | 12 - packages/solana/src/utils/utils.ts | 45 +++ pnpm-lock.yaml | 278 ++++++++---------- 15 files changed, 430 insertions(+), 388 deletions(-) delete mode 100644 packages/solana/src/providers/solflareProvider.ts delete mode 100644 packages/solana/src/types/chainConfig.ts delete mode 100644 packages/solana/src/types/index.ts delete mode 100644 packages/solana/src/utils/emiter.ts create mode 100644 packages/solana/src/utils/utils.ts diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index ea993b5..348fac9 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -15,6 +15,7 @@ "@wallet01/evm": "workspace:*", "@wallet01/react": "workspace:*", "@wallet01/cosmos": "workspace:*", + "@wallet01/solana": "workspace:*", "ethers": "^5.7.2", "next": "13.0.3", "react": "18.2.0", diff --git a/examples/nextjs/pages/_app.tsx b/examples/nextjs/pages/_app.tsx index e33e0ac..2a88875 100644 --- a/examples/nextjs/pages/_app.tsx +++ b/examples/nextjs/pages/_app.tsx @@ -10,7 +10,7 @@ import { OkxWalletConnector, } from "@wallet01/evm"; import { KeplrConnector } from "@wallet01/cosmos"; -// import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; +import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; // import { BeaconConnector, TempleConnector } from "@wallet01/tezos"; import Layout from "../components/layout"; // import { ColorMode } from "@wallet01/tezos/dist/types"; @@ -32,12 +32,8 @@ export default function App({ Component, pageProps }: AppProps) { CoinbaseConnector.init({ appName: "Wallet01", }), - // new PhantomConnector({ - // rpcUrl: "https://api.mainnet-beta.solana.com", - // }), - // new SolflareConnector({ - // rpcUrl: "https://api.mainnet-beta.solana.com", - // }), + PhantomConnector.init(), + SolflareConnector.init(), KeplrConnector.init("osmosis"), // new TempleConnector({ projectName: "Wallet01" }), // new BeaconConnector({ diff --git a/packages/core/src/utils/errors.ts b/packages/core/src/utils/errors.ts index e75599d..0c7bbd7 100644 --- a/packages/core/src/utils/errors.ts +++ b/packages/core/src/utils/errors.ts @@ -97,3 +97,18 @@ export class UnrecognisedChainError extends Error { ); } } + +export class AddressNotFoundError extends Error { + name = "AddressNotFoundError"; + constructor({ walletName }: { walletName: string }) { + super(`Address not found in ${walletName} wallet.`); + } +} + +export class WalletNotInstalledError extends Error { + name = "WalletNotInstalledError"; + + constructor({ walletName }: { walletName: string }) { + super(`${walletName} wallet is not installed.`); + } +} diff --git a/packages/evm/package.json b/packages/evm/package.json index 37a00eb..4dc67f9 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -20,7 +20,6 @@ "@walletconnect/ethereum-provider": "^2.8.2", "@walletconnect/modal": "^2.5.2", "@web3modal/core": "^2.2.2", - "@web3modal/standalone": "^2.2.2", "ethers": "^5.7.2", "eventemitter3": "^4.0.7" }, diff --git a/packages/solana/package.json b/packages/solana/package.json index 2ed4a98..7140637 100644 --- a/packages/solana/package.json +++ b/packages/solana/package.json @@ -12,11 +12,10 @@ "dev": "pnpm build --watch" }, "dependencies": { - "@bonfida/spl-name-service": "^0.1.55", - "@solana/web3.js": "^1.66.2", + "@solana/web3.js": "^1.87.1", + "@solflare-wallet/sdk": "^1.3.2", "@wallet01/core": "workspace:*", - "eventemitter3": "^4.0.7", - "tweetnacl": "^1.0.3" + "eventemitter3": "^4.0.7" }, "devDependencies": { "rimraf": "^3.0.2", diff --git a/packages/solana/src/connectors/phantom.ts b/packages/solana/src/connectors/phantom.ts index 7a81160..17cb162 100644 --- a/packages/solana/src/connectors/phantom.ts +++ b/packages/solana/src/connectors/phantom.ts @@ -1,9 +1,16 @@ -import { Connection, PublicKey } from "@solana/web3.js"; -import { performReverseLookup, getAllDomains } from "@bonfida/spl-name-service"; - -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + AddressNotFoundError, + BaseConnector, + ProviderNotFoundError, + UnknownError, + WalletNotConnectedError, +} from "@wallet01/core"; import { PhantomProvider } from "../providers/phantomProvider"; -import emitter from "../utils/emiter"; +import { + ConnectionResponse, + MessageSignedResponse, +} from "@wallet01/core/dist/types/methodTypes"; +import { SolanaErrorHandler } from "../utils/utils"; interface PhantomWindow extends Window { solana?: PhantomProvider; @@ -11,108 +18,131 @@ interface PhantomWindow extends Window { declare const window: PhantomWindow; -interface PhantomConnectorOptions { - rpcUrl: string; -} - export class PhantomConnector extends BaseConnector { + static #instance: BaseConnector; provider!: PhantomProvider; - private rpcUrl: string; - constructor({ rpcUrl }: PhantomConnectorOptions) { - super("", "phantom", "solana"); - this.rpcUrl = rpcUrl; + private constructor() { + super("phantom", "solana"); } - async getProvider(): Promise { - if ( - typeof window !== "undefined" && - window.solana && - window.solana.isPhantom - ) { - this.provider = window.solana; - return this.provider; - } else { - throw new Error("Wallet Not Installed"); + static init() { + if (!PhantomConnector.#instance) { + PhantomConnector.#instance = + new PhantomConnector() as BaseConnector; } + return PhantomConnector.#instance; } - async getAccount(): Promise { - if (!this.provider) throw new Error("Provider Undefined"); + async getProvider() { try { - await this.connect(""); - const accounts = this.provider.publicKey; - return [String(accounts)]; + if ( + typeof window !== "undefined" && + window.solana && + window.solana.isPhantom + ) { + this.provider = window.solana; + return this.provider; + } + throw new ProviderNotFoundError({ walletName: this.name }); } catch (error) { console.error(error); - throw error; + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); } } - async connect({}): Promise { + async getAccount(): Promise { + if (!this.provider) throw new Error("Provider Undefined"); try { - const provider = await this.getProvider(); - if (!provider) throw new Error("Phantom is not installed"); - await this.provider.connect(); - setLastUsedConnector(this.name); - - if (provider.on) { - provider.on("accountChanged", this.onAccountsChanged); - provider.on("disconnect", this.onDisconnect); - } + const account = this.provider.publicKey?.toString(); + if (!account) throw new AddressNotFoundError({ walletName: this.name }); + return [account]; } catch (error) { console.error(error); - throw error; + throw SolanaErrorHandler(error, "getAccount", this.name); } } - async disconnect(): Promise { - if (!this.provider) throw new Error("No wallet Conencted"); - this.provider.disconnect(); - emitter.emit("disconnected"); - } + async connect(): Promise { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) throw new Error("Provider Undefined"); + const { publicKey } = await this.provider.connect(); + + this.provider.on("accountChanged", this.onAccountsChanged); + this.provider.on("disconnect", this.onDisconnect); + + this.emitter.emit( + "connected", + publicKey.toString(), + "mainnet", + this.name, + this.ecosystem, + PhantomConnector.#instance + ); - async resolveDid(address: string): Promise { - if (!this.provider) throw new Error("No wallet Connected"); - const connection = new Connection(this.rpcUrl); + return { + address: publicKey.toString(), + chainId: "mainnet", + ecosystem: this.ecosystem, + walletName: this.name, + activeConnector: PhantomConnector.#instance, + }; + } catch (error) { + console.error(error); + throw SolanaErrorHandler(error, "connect", this.name); + } + } + async disconnect() { + if (!this.provider) await this.getProvider(); try { - const ownerWallet = new PublicKey(address); - const allDomainKeys = await getAllDomains(connection, ownerWallet); - const allDomainNames = await Promise.all( - allDomainKeys.map(key => { - return performReverseLookup(connection, key); - }) - ); - if (!allDomainNames[0]) return null; - return allDomainNames[0]; + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + this.provider.disconnect(); + + this.emitter.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { console.error(error); - throw error; + throw SolanaErrorHandler(error, "disconnect", this.name); } } - async signMessage(message: string): Promise { - if (!this.provider) throw new Error("No wallet Connected"); + async signMessage(message: string): Promise { + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - const _message = new TextEncoder().encode(message); - const { signature } = await this.provider.signMessage(_message); - return new TextDecoder("utf-8").decode(signature); + const encodedMessage = new TextEncoder().encode(message); + const { signature } = await this.provider.signMessage( + encodedMessage, + "utf8" + ); + + this.emitter.emit("messageSigned", signature, PhantomConnector.#instance); + + return { + signature, + activeConnector: PhantomConnector.#instance, + }; } catch (err) { console.error(err); - throw err; + throw SolanaErrorHandler(err, "signMessage", this.name); } } - protected onAccountsChanged(): void { - console.log("Account Changed"); - } - - protected onChainChanged(_chain: string | number): void { - console.log("Chain Changed"); + protected onAccountsChanged(accounts: string[]): void { + this.emitter.emit("accountsChanged", accounts, PhantomConnector.#instance); } - protected onDisconnect(): void { - console.log("Wallet disconnected"); + protected onDisconnect(error: any): void { + console.error(error); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/solana/src/connectors/solflare.ts b/packages/solana/src/connectors/solflare.ts index 0cda4be..8fef87b 100644 --- a/packages/solana/src/connectors/solflare.ts +++ b/packages/solana/src/connectors/solflare.ts @@ -1,118 +1,150 @@ -import { Connection, PublicKey } from "@solana/web3.js"; -import { performReverseLookup, getAllDomains } from "@bonfida/spl-name-service"; -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; - -import { SolflareProvider } from "../providers/solflareProvider"; -import emitter from "../utils/emiter"; - -declare const window: { - solflare: SolflareProvider; -}; - -interface SolflareConnectorOptions { - rpcUrl: string; -} +import { + AddressNotFoundError, + BaseConnector, + ProviderNotFoundError, + WalletNotConnectedError, +} from "@wallet01/core"; + +import SolflareProvider from "@solflare-wallet/sdk"; +import { SolanaErrorHandler } from "../utils/utils"; +import { + ConnectionResponse, + DisconnectionResponse, + MessageSignedResponse, +} from "@wallet01/core/dist/types/methodTypes"; +import { WalletNotInstalledError } from "@wallet01/core"; export class SolflareConnector extends BaseConnector { + static #instance: BaseConnector; provider!: SolflareProvider; - private rpcUrl: string; - constructor({ rpcUrl }: SolflareConnectorOptions) { - super("", "solflare", "solana"); + private constructor() { + super("solflare", "solana"); + } - this.rpcUrl = rpcUrl; + static init() { + if (!SolflareConnector.#instance) { + SolflareConnector.#instance = + new SolflareConnector() as BaseConnector; + } + return SolflareConnector.#instance; } async getProvider(): Promise { - if ( - typeof window !== "undefined" && - window.solflare && - window.solflare.isSolflare - ) { - this.provider = window.solflare; + try { + const provider = new SolflareProvider(); + const isWalletInstalled = await provider.detectWallet(); + if (!isWalletInstalled) + throw new WalletNotInstalledError({ walletName: this.name }); + this.provider = provider; return this.provider; - } else { - throw new Error("Wallet Not Installed"); + } catch (error) { + console.error(error); + throw SolanaErrorHandler(error, "getProvider", this.name); } } async getAccount(): Promise { - if (!this.provider) throw new Error("Provider Undefined"); + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - await this.provider.connect(); - const accounts = this.provider.publicKey; - return [String(accounts)]; + const account = this.provider.publicKey?.toString(); + if (!account) throw new AddressNotFoundError({ walletName: this.name }); + return [account]; } catch (error) { console.error(error); - throw error; + throw SolanaErrorHandler(error, "getAccount", this.name); } } - async connect({}): Promise { + async connect(): Promise { + if (!this.provider) await this.getProvider(); try { - const provider = await this.getProvider(); - if (!provider) throw new Error("Solflare is not installed"); - - if (provider.on) { - provider.on("accountChanged", this.onAccountsChanged); - provider.on("disconnect", this.onDisconnect); - } + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); await this.provider.connect(); - setLastUsedConnector(this.name); + + this.provider.on("accountChanged", this.onAccountsChanged); + this.provider.on("disconnect", this.onDisconnect); + + const address = this.provider.publicKey?.toString()!; + const chainId = "mainnet"; + + this.emitter.emit( + "connected", + address, + chainId, + this.name, + this.ecosystem, + SolflareConnector.#instance + ); + + return { + address, + chainId, + ecosystem: this.ecosystem, + walletName: this.name, + activeConnector: SolflareConnector.#instance, + }; } catch (error) { console.error(error); - throw error; + throw SolanaErrorHandler(error, "connect", this.name); } } - async disconnect(): Promise { - if (!this.provider) throw new Error("No wallet Conencted"); - this.provider.disconnect(); - emitter.emit("disconnected"); - } + async disconnect(): Promise { + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); + try { + this.provider.disconnect(); - async resolveDid(address: string): Promise { - if (!this.provider) throw new Error("No wallet Connected"); - const connection = new Connection(this.rpcUrl); + this.provider.removeListener("accountChanged", this.onAccountsChanged); + this.provider.removeListener("disconnect", this.onDisconnect); - try { - const ownerWallet = new PublicKey(address); - const allDomainKeys = await getAllDomains(connection, ownerWallet); - const allDomainNames = await Promise.all( - allDomainKeys.map(key => { - return performReverseLookup(connection, key); - }) - ); - if (!allDomainNames[0]) return null; - return allDomainNames[0]; + this.emitter.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { console.error(error); - throw error; + throw SolanaErrorHandler(error, "disconnect", this.name); } } - async signMessage(message: string): Promise { - if (!this.provider) throw new Error("No wallet Connected"); + async signMessage(message: string): Promise { + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - const _message = new TextEncoder().encode(message); - const hash = await this.provider.signMessage(_message, "utf8"); - return new TextDecoder("utf-8").decode(hash); + const encodedMessage = new TextEncoder().encode(message); + const signature = await this.provider.signMessage(encodedMessage, "utf8"); + + this.emitter.emit( + "messageSigned", + signature, + SolflareConnector.#instance + ); + + return { + signature, + activeConnector: SolflareConnector.#instance, + }; } catch (err) { console.error(err); - throw err; + throw SolanaErrorHandler(err, "signMessage", this.name); } } - protected onAccountsChanged(): void { - console.log("Account Changed"); - } - - protected onChainChanged(_chain: string | number): void { - console.log("Chain Changed"); + protected onAccountsChanged(address: string): void { + this.emitter.emit( + "accountsChanged", + [address], + SolflareConnector.#instance + ); } protected onDisconnect(): void { - console.log("Wallet disconnected"); + this.emitter.emit("disconnected", this.name, this.ecosystem); } } diff --git a/packages/solana/src/index.ts b/packages/solana/src/index.ts index 505b501..0edaf08 100644 --- a/packages/solana/src/index.ts +++ b/packages/solana/src/index.ts @@ -2,11 +2,5 @@ import { SolflareConnector } from "./connectors/solflare"; import { PhantomConnector } from "./connectors/phantom"; import { PhantomProvider } from "./providers/phantomProvider"; -import { SolflareProvider } from "./providers/solflareProvider"; -export { - SolflareConnector, - type SolflareProvider, - PhantomConnector, - type PhantomProvider, -}; +export { SolflareConnector, PhantomConnector, type PhantomProvider }; diff --git a/packages/solana/src/providers/phantomProvider.ts b/packages/solana/src/providers/phantomProvider.ts index 7fca704..6f2f035 100644 --- a/packages/solana/src/providers/phantomProvider.ts +++ b/packages/solana/src/providers/phantomProvider.ts @@ -1,21 +1,35 @@ -import { - SendOptions, - Transaction, - TransactionSignature, -} from '@solana/web3.js'; -import EventEmitter from 'eventemitter3'; +import { PublicKey } from "@solana/web3.js"; -export interface PhantomProvider extends EventEmitter { +type DisplayEncoding = "utf8" | "hex"; +interface ConnectOpts { + onlyIfTrusted: boolean; +} + +type PhantomEvent = "connect" | "disconnect" | "accountChanged"; + +type PhantomRequestMethod = + | "connect" + | "disconnect" + | "signAndSendTransaction" + | "signAndSendTransactionV0" + | "signAndSendTransactionV0WithLookupTable" + | "signTransaction" + | "signAllTransactions" + | "signMessage"; + +export interface PhantomProvider { + publicKey: PublicKey | null; + isConnected: boolean | null; isPhantom?: boolean; - publicKey?: { toBytes(): Uint8Array }; - isConnected: boolean; - signTransaction(transaction: Transaction): Promise; - signAllTransactions(transactions: Transaction[]): Promise; - signAndSendTransaction( - transaction: Transaction, - options?: SendOptions - ): Promise<{ signature: TransactionSignature }>; - signMessage(message: Uint8Array): Promise<{ signature: Uint8Array }>; - connect(): Promise; - disconnect(): Promise; + signMessage: ( + message: Uint8Array | string, + display?: DisplayEncoding + ) => Promise<{ + signature: Uint8Array; + publicKey: PublicKey; + }>; + connect: (opts?: Partial) => Promise<{ publicKey: PublicKey }>; + disconnect: () => Promise; + on: (event: PhantomEvent, handler: (args: any) => void) => void; + request: (method: PhantomRequestMethod, params: any) => Promise; } diff --git a/packages/solana/src/providers/solflareProvider.ts b/packages/solana/src/providers/solflareProvider.ts deleted file mode 100644 index be1d505..0000000 --- a/packages/solana/src/providers/solflareProvider.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { PublicKey } from '@solana/web3.js'; -import EventEmitter from 'eventemitter3'; - -export interface SolflareProvider extends EventEmitter { - isSolflare?: boolean; - - publicKey(): PublicKey | null; - connected(): boolean; - - connect(): Promise; - disconnect(): Promise; - signTransaction(message: Uint8Array): Promise; - signAllTransactions(messages: Uint8Array[]): Promise; - signMessage(data: Uint8Array, display: 'hex' | 'utf8'): Promise; -} diff --git a/packages/solana/src/types/chainConfig.ts b/packages/solana/src/types/chainConfig.ts deleted file mode 100644 index f91530f..0000000 --- a/packages/solana/src/types/chainConfig.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type CustomChainConfig = { - chainNamespace: 'eip155' | 'solana' | 'other'; - chainId: string; - rpcTarget?: string; - displayName: string; - blockExplorer?: string; - ticker: string; - tickerName: string; -}; diff --git a/packages/solana/src/types/index.ts b/packages/solana/src/types/index.ts deleted file mode 100644 index e454ea7..0000000 --- a/packages/solana/src/types/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CustomChainConfig } from './chainConfig'; -import { BaseConnector } from '@wallet01/core'; - -type ClientConfig = { - chainConfig: CustomChainConfig; - connector: BaseConnector; -}; - -type ConnectedData = { - account: string; - chainId: string; - provider: TProvider; -}; - -export { type CustomChainConfig, type ClientConfig, type ConnectedData }; diff --git a/packages/solana/src/utils/emiter.ts b/packages/solana/src/utils/emiter.ts deleted file mode 100644 index 17c4b4b..0000000 --- a/packages/solana/src/utils/emiter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import EventEmitter from 'eventemitter3'; - -const eventEmitter = new EventEmitter(); -const emitter = { - on: (event: string, fn: (args: any) => void) => eventEmitter.on(event, fn), - once: (event: string, fn: () => void) => eventEmitter.once(event, fn), - off: (event: string, fn: () => void) => eventEmitter.off(event, fn), - emit: (event: string, payload?: unknown) => eventEmitter.emit(event, payload), -}; - -Object.freeze(emitter); -export default emitter; diff --git a/packages/solana/src/utils/utils.ts b/packages/solana/src/utils/utils.ts new file mode 100644 index 0000000..1d377f4 --- /dev/null +++ b/packages/solana/src/utils/utils.ts @@ -0,0 +1,45 @@ +import { UnknownError, UserRejectedRequestError } from "@wallet01/core"; + +export class WalletInternalError extends Error { + name = "WalletInternalError"; + + constructor({ walletName }: { walletName: string }) { + super(`There was an internal error while using ${walletName} wallet.`); + } +} + +export class UnauthorisedMethodError extends Error { + name = "UnauthorisedMethodError"; + + constructor({ method, walletName }: { method: string; walletName: string }) { + super( + `Method ${method} is not authorised by the user for ${walletName} wallet.` + ); + } +} + +export const SolanaErrorHandler = ( + error: any, + atFunction: string, + walletName: string +) => { + switch (error.code) { + case 4100: + throw new UnauthorisedMethodError({ + method: atFunction, + walletName, + }); + + case 4001: + throw new UserRejectedRequestError(); + + case -32603: + throw new WalletInternalError({ walletName }); + + default: + throw new UnknownError({ + walletName, + atFunction, + }); + } +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1f1a89..96aacbb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: '@wallet01/react': specifier: workspace:* version: link:../../packages/react + '@wallet01/solana': + specifier: workspace:* + version: link:../../packages/solana ethers: specifier: ^5.7.2 version: 5.7.2 @@ -228,9 +231,6 @@ importers: '@web3modal/core': specifier: ^2.2.2 version: 2.2.2 - '@web3modal/standalone': - specifier: ^2.2.2 - version: 2.2.2 ethers: specifier: ^5.7.2 version: 5.7.2 @@ -284,21 +284,18 @@ importers: packages/solana: dependencies: - '@bonfida/spl-name-service': - specifier: ^0.1.55 - version: 0.1.55(@solana/spl-token@0.1.8)(@solana/web3.js@1.66.2)(bn.js@5.2.1)(borsh@0.6.0) '@solana/web3.js': - specifier: ^1.66.2 - version: 1.66.2 + specifier: ^1.87.1 + version: 1.87.1 + '@solflare-wallet/sdk': + specifier: ^1.3.2 + version: 1.3.2(@solana/web3.js@1.87.1) '@wallet01/core': specifier: workspace:* version: link:../core eventemitter3: specifier: ^4.0.7 version: 4.0.7 - tweetnacl: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: rimraf: specifier: ^3.0.2 @@ -719,6 +716,13 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: false + /@babel/template@7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} engines: {node: '>=6.9.0'} @@ -755,45 +759,6 @@ packages: to-fast-properties: 2.0.0 dev: true - /@bonfida/name-offers@0.0.1: - resolution: {integrity: sha512-R0GJ/+R5OXfm4KfiKEjHx88QnQxw+kzDA8O4pHouev1voPJueOzzo5x+YLowMpk3/2maqEwkNPWiWIlSExjdug==} - dependencies: - '@bonfida/spl-name-service': 0.1.55(@solana/spl-token@0.1.8)(@solana/web3.js@1.66.2)(bn.js@5.2.1)(borsh@0.6.0) - '@solana/spl-token': 0.1.8 - '@solana/web3.js': 1.66.2 - bn.js: 5.2.1 - borsh: 0.6.0 - bs58: 4.0.1 - transitivePeerDependencies: - - '@solana/buffer-layout' - - bufferutil - - encoding - - supports-color - - utf-8-validate - dev: false - - /@bonfida/spl-name-service@0.1.55(@solana/spl-token@0.1.8)(@solana/web3.js@1.66.2)(bn.js@5.2.1)(borsh@0.6.0): - resolution: {integrity: sha512-Yv9OVAWzVzVIvOOIkPWRIWHCf0S/tJx7VVMboJB9eojcRT1IWGPhQs0yy6XzCSX9SjoJSk4ZjUY4cRhCeNeknQ==} - peerDependencies: - '@solana/buffer-layout': ^4.0.0 - '@solana/spl-token': 0.2.0 - '@solana/web3.js': ^1.37.1 - bn.js: ^5.1.3 - borsh: ^0.7.0 - dependencies: - '@bonfida/name-offers': 0.0.1 - '@ethersproject/sha2': 5.7.0 - '@solana/spl-token': 0.1.8 - '@solana/web3.js': 1.66.2 - bn.js: 5.2.1 - borsh: 0.6.0 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate - dev: false - /@changesets/apply-release-plan@6.1.2: resolution: {integrity: sha512-H8TV9E/WtJsDfoDVbrDGPXmkZFSv7W2KLqp4xX4MKZXshb0hsQZUNowUa8pnus9qb/5OZrFFRVsUsDCVHNW/AQ==} dependencies: @@ -1690,6 +1655,12 @@ packages: dev: false optional: true + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + /@noble/ed25519@1.7.1: resolution: {integrity: sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==} dev: false @@ -1698,6 +1669,11 @@ packages: resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} dev: false + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + /@noble/secp256k1@1.7.0: resolution: {integrity: sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==} dev: false @@ -1758,25 +1734,8 @@ packages: buffer: 6.0.3 dev: false - /@solana/spl-token@0.1.8: - resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} - engines: {node: '>= 10'} - dependencies: - '@babel/runtime': 7.20.1 - '@solana/web3.js': 1.73.0 - bn.js: 5.2.1 - buffer: 6.0.3 - buffer-layout: 1.2.2 - dotenv: 10.0.0 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate - dev: false - - /@solana/web3.js@1.66.2: - resolution: {integrity: sha512-RyaHMR2jGmaesnYP045VLeBGfR/gAW3cvZHzMFGg7bkO+WOYOYp1nEllf0/la4U4qsYGKCsO9eEevR5fhHiVHg==} + /@solana/web3.js@1.73.0: + resolution: {integrity: sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==} engines: {node: '>=12.20.0'} dependencies: '@babel/runtime': 7.20.1 @@ -1784,6 +1743,7 @@ packages: '@noble/hashes': 1.1.3 '@noble/secp256k1': 1.7.0 '@solana/buffer-layout': 4.0.0 + agentkeepalive: 4.2.1 bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 @@ -1797,36 +1757,45 @@ packages: transitivePeerDependencies: - bufferutil - encoding + - supports-color - utf-8-validate dev: false - /@solana/web3.js@1.73.0: - resolution: {integrity: sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==} - engines: {node: '>=12.20.0'} + /@solana/web3.js@1.87.1: + resolution: {integrity: sha512-E8Y9bNlZ8TQlhOvCx1b7jG+TjA4SJLVwufmIk1+tcQctUhK5HiB1Q8ljd4yQDkFlk6OOeAlAeqvW0YntWJU94Q==} dependencies: - '@babel/runtime': 7.20.1 - '@noble/ed25519': 1.7.1 - '@noble/hashes': 1.1.3 - '@noble/secp256k1': 1.7.0 + '@babel/runtime': 7.23.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 '@solana/buffer-layout': 4.0.0 - agentkeepalive: 4.2.1 + agentkeepalive: 4.5.0 bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 - buffer: 6.0.1 + buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 3.7.0 - node-fetch: 2.6.7 - rpc-websockets: 7.5.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.6.0 superstruct: 0.14.2 transitivePeerDependencies: - bufferutil - encoding - - supports-color - utf-8-validate dev: false + /@solflare-wallet/sdk@1.3.2(@solana/web3.js@1.87.1): + resolution: {integrity: sha512-jXOCogqYWIpvgKRWBUlt9HZTH25u2qAvaufVh/ooQlVyFbCUb03XKuMxPcUk29ZelU3PTKy6nCcWDc+cImfPpA==} + peerDependencies: + '@solana/web3.js': '*' + dependencies: + '@solana/web3.js': 1.87.1 + bs58: 5.0.0 + eventemitter3: 5.0.1 + uuid: 9.0.0 + dev: false + /@stablelib/aead@1.0.1: resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} dev: false @@ -2784,27 +2753,6 @@ packages: - react dev: false - /@web3modal/standalone@2.2.2: - resolution: {integrity: sha512-c05kkTFNGZqnjJ3n2C8uo+wWL6ut1jexGYAyTvbweDengdsOr8LDo0VpK5V3XSKCV2fFcPh5JE9H1aA4jpnZPg==} - deprecated: This package has been deprecated in favor of @walletconnect/modal. Please read more at https://docs.walletconnect.com - dependencies: - '@web3modal/core': 2.2.2 - '@web3modal/ui': 2.2.2 - transitivePeerDependencies: - - react - dev: false - - /@web3modal/ui@2.2.2: - resolution: {integrity: sha512-PAuMOuk4sZ4UGjucGMZKzu6Qu56XtFsgLaqOn8ZgP2RkZmYEBGSG9mUQVzJd3XzfzAy1T91Wmqp/3TI3m0pXuQ==} - dependencies: - '@web3modal/core': 2.2.2 - lit: 2.6.1 - motion: 10.15.5 - qrcode: 1.5.1 - transitivePeerDependencies: - - react - dev: false - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} dependencies: @@ -2865,6 +2813,13 @@ packages: - supports-color dev: false + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -3092,6 +3047,10 @@ packages: safe-buffer: 5.2.1 dev: false + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false @@ -3146,14 +3105,6 @@ packages: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} dev: false - /borsh@0.6.0: - resolution: {integrity: sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q==} - dependencies: - bn.js: 5.2.1 - bs58: 4.0.1 - text-encoding-utf-8: 1.0.2 - dev: false - /borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} dependencies: @@ -3250,6 +3201,12 @@ packages: base-x: 3.0.9 dev: false + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + /bs58check@2.1.2: resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} dependencies: @@ -3258,11 +3215,6 @@ packages: safe-buffer: 5.2.1 dev: false - /buffer-layout@1.2.2: - resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} - engines: {node: '>=4.5'} - dev: false - /buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: false @@ -3709,11 +3661,6 @@ packages: dependencies: esutils: 2.0.3 - /dotenv@10.0.0: - resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} - engines: {node: '>=10'} - dev: false - /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} @@ -4512,6 +4459,10 @@ packages: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: false + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -5186,6 +5137,28 @@ packages: - utf-8-validate dev: false + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.35 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -5343,14 +5316,6 @@ packages: '@types/trusted-types': 2.0.3 dev: false - /lit@2.6.1: - resolution: {integrity: sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==} - dependencies: - '@lit/reactive-element': 1.6.2 - lit-element: 3.3.2 - lit-html: 2.7.5 - dev: false - /lit@2.7.5: resolution: {integrity: sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==} dependencies: @@ -5551,17 +5516,6 @@ packages: engines: {node: '>= 8.0.0'} dev: true - /motion@10.15.5: - resolution: {integrity: sha512-ejP6KioN4pigTGxL93APzOnvtLklParL59UQB2T3HWXQBxFcIp5/7YXFmkgiA6pNKKzjvnLhnonRBN5iSFMnNw==} - dependencies: - '@motionone/animation': 10.15.1 - '@motionone/dom': 10.16.2 - '@motionone/svelte': 10.16.2 - '@motionone/types': 10.15.1 - '@motionone/utils': 10.15.1 - '@motionone/vue': 10.16.2 - dev: false - /motion@10.16.2: resolution: {integrity: sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ==} dependencies: @@ -5663,6 +5617,18 @@ packages: whatwg-url: 5.0.0 dev: false + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + /node-gyp-build@4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} dev: false @@ -6129,17 +6095,6 @@ packages: hasBin: true dev: false - /qrcode@1.5.1: - resolution: {integrity: sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==} - engines: {node: '>=10.13.0'} - hasBin: true - dependencies: - dijkstrajs: 1.0.2 - encode-utf8: 1.0.3 - pngjs: 5.0.0 - yargs: 15.4.1 - dev: false - /qrcode@1.5.3: resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} engines: {node: '>=10.13.0'} @@ -6316,6 +6271,10 @@ packages: /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: false + /regexp.prototype.flags@1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} @@ -6409,6 +6368,18 @@ packages: utf-8-validate: 5.0.10 dev: false + /rpc-websockets@7.6.0: + resolution: {integrity: sha512-Jgcs8q6t8Go98dEulww1x7RysgTkzpCMelVxZW4hvuyFtOGpeUz9prpr2KjUa/usqxgFCd9Tu3+yhHEP9GVmiQ==} + dependencies: + '@babel/runtime': 7.23.2 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.11.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.7 + utf-8-validate: 5.0.10 + dev: false + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -7060,10 +7031,6 @@ packages: turbo-windows-arm64: 1.10.15 dev: true - /tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - dev: false - /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7184,6 +7151,7 @@ packages: /uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true dev: false /v8-compile-cache@2.3.0: From 02551d4227c54236201c8c34206ac1543748627f Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 17:04:35 +0530 Subject: [PATCH 10/17] feat: updated tezos connectors --- examples/nextjs/components/ConnectButtons.tsx | 2 +- examples/nextjs/package.json | 1 + examples/nextjs/pages/_app.tsx | 15 +- examples/nextjs/pages/index.tsx | 4 - packages/tezos/package.json | 5 +- .../tezos/src/connectors/BeaconConnector.ts | 235 +++++++++------- .../tezos/src/connectors/TempleConnector.ts | 169 ------------ packages/tezos/src/index.ts | 3 +- pnpm-lock.yaml | 258 ++++++------------ 9 files changed, 229 insertions(+), 463 deletions(-) delete mode 100644 packages/tezos/src/connectors/TempleConnector.ts diff --git a/examples/nextjs/components/ConnectButtons.tsx b/examples/nextjs/components/ConnectButtons.tsx index 7bf2117..c3c3247 100644 --- a/examples/nextjs/components/ConnectButtons.tsx +++ b/examples/nextjs/components/ConnectButtons.tsx @@ -4,7 +4,7 @@ import WalletIcons from "./assets/WalletIcons"; const ConnectButtons = () => { const { connectors } = useClient(); - const { activeConnector, isConnected, address } = useWallet(); + const { activeConnector, isConnected } = useWallet(); const { connect, isError, error } = useConnect(); if (isError && error) { diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 348fac9..0ad0d2c 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -16,6 +16,7 @@ "@wallet01/react": "workspace:*", "@wallet01/cosmos": "workspace:*", "@wallet01/solana": "workspace:*", + "@wallet01/tezos": "workspace:*", "ethers": "^5.7.2", "next": "13.0.3", "react": "18.2.0", diff --git a/examples/nextjs/pages/_app.tsx b/examples/nextjs/pages/_app.tsx index 2a88875..3836a03 100644 --- a/examples/nextjs/pages/_app.tsx +++ b/examples/nextjs/pages/_app.tsx @@ -11,9 +11,9 @@ import { } from "@wallet01/evm"; import { KeplrConnector } from "@wallet01/cosmos"; import { PhantomConnector, SolflareConnector } from "@wallet01/solana"; -// import { BeaconConnector, TempleConnector } from "@wallet01/tezos"; +import { BeaconConnector } from "@wallet01/tezos"; import Layout from "../components/layout"; -// import { ColorMode } from "@wallet01/tezos/dist/types"; +import { ColorMode } from "@wallet01/tezos/dist/types"; export default function App({ Component, pageProps }: AppProps) { return ( @@ -35,12 +35,11 @@ export default function App({ Component, pageProps }: AppProps) { PhantomConnector.init(), SolflareConnector.init(), KeplrConnector.init("osmosis"), - // new TempleConnector({ projectName: "Wallet01" }), - // new BeaconConnector({ - // name: "Wallet01", - // featuredWallets: ["temple", "umami", "kukai", "naan"], - // colorMode: ColorMode.DARK, - // }), + BeaconConnector.init({ + name: "Wallet01", + featuredWallets: ["temple", "umami", "kukai", "naan"], + colorMode: ColorMode.DARK, + }), ]} > diff --git a/examples/nextjs/pages/index.tsx b/examples/nextjs/pages/index.tsx index a9b8d03..12a5602 100644 --- a/examples/nextjs/pages/index.tsx +++ b/examples/nextjs/pages/index.tsx @@ -11,10 +11,6 @@ export default function Home() { // const { isAutoConnecting } = useClient(); const { isConnected } = useWallet(); - console.log({ - isConnected, - }); - return (
{/* {isAutoConnecting ? ( diff --git a/packages/tezos/package.json b/packages/tezos/package.json index a859314..dcd5b88 100644 --- a/packages/tezos/package.json +++ b/packages/tezos/package.json @@ -14,9 +14,8 @@ "keywords": [], "author": "thevatsal.eth", "dependencies": { - "@taquito/beacon-wallet": "^17.1.0", - "@taquito/taquito": "12.0.0", - "@temple-wallet/dapp": "^7.0.0", + "@taquito/beacon-wallet": "^17.3.1", + "@taquito/taquito": "^17.3.1", "@wallet01/core": "workspace:*" }, "devDependencies": { diff --git a/packages/tezos/src/connectors/BeaconConnector.ts b/packages/tezos/src/connectors/BeaconConnector.ts index 9a58391..71797d1 100644 --- a/packages/tezos/src/connectors/BeaconConnector.ts +++ b/packages/tezos/src/connectors/BeaconConnector.ts @@ -1,119 +1,149 @@ -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; +import { + AddressNotFoundError, + BaseConnector, + ProviderNotFoundError, + UnknownError, + WalletNotConnectedError, +} from "@wallet01/core"; import { TezosToolkit } from "@taquito/taquito"; import { BeaconWallet } from "@taquito/beacon-wallet"; import { formatMessage } from "../utils/formatMessage"; import { isNetwork } from "../utils/isNetwork"; import { PermissionScope, SigningType, DAppClientOptions } from "../types"; +import { + ConnectionResponse, + DisconnectionResponse, + MessageSignedResponse, +} from "@wallet01/core/dist/types/methodTypes"; type BeaconConnectorOptions = { - chain?: string; name: string; rpcUrl?: string; } & DAppClientOptions; export class BeaconConnector extends BaseConnector { - provider?: BeaconWallet | undefined; - private projectName: string; + static #instance: BaseConnector; + provider!: BeaconWallet; private rpcUrl: string; - private featuredWallets?: string[]; - private toolkit: TezosToolkit; + private toolkit!: TezosToolkit; + private isConnected = false; + private options: DAppClientOptions; - static publicKey?: string; - - constructor({ - chain = "mainnet", - name, - rpcUrl, - featuredWallets, - }: BeaconConnectorOptions) { - super(chain, "beacon", "tezos"); - this.projectName = name; - this.featuredWallets = featuredWallets; + private constructor({ rpcUrl, ...options }: BeaconConnectorOptions) { + super("beacon", "tezos"); + this.options = options; if (rpcUrl) { this.rpcUrl = rpcUrl; } else { this.rpcUrl = "https://mainnet.api.tez.ie/"; } + } - this.toolkit = new TezosToolkit(this.rpcUrl); + static init(options: BeaconConnectorOptions) { + if (!BeaconConnector.#instance) { + BeaconConnector.#instance = new BeaconConnector( + options + ) as BaseConnector; + } + return BeaconConnector.#instance; } async getProvider(): Promise { try { - if (!this.provider) { - const provider = new BeaconWallet({ - name: this.projectName, - featuredWallets: this.featuredWallets, - }); + if (!this.toolkit) this.toolkit = new TezosToolkit(this.rpcUrl); + if (!this.isConnected) { + const provider = new BeaconWallet(this.options); this.provider = provider; this.toolkit.setProvider({ wallet: provider }); } return this.provider; } catch (error) { - console.error({ error }, "getProvider"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); } } async getAccount(): Promise { - if (!this.provider) await this.getProvider(); + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - if (!this.provider) throw new Error("Wallet Not Installed"); const account = await this.provider.getPKH(); - if (!account) { - throw new Error("Wallet Not Conencted"); - } return [account]; } catch (error) { - console.error({ error }, "getAccount"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); } } async getChainId(): Promise { - if (!this.provider) await this.getProvider(); + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { if (!this.provider) throw new Error("Wallet Not Installed"); const account = await this.provider.client.getActiveAccount(); if (!account) { - await this.connect({}); - return this.chain; + throw new WalletNotConnectedError({ walletName: this.name }); } const { - network: { type }, + network: { type: chainId }, } = account; - return type; + return chainId; } catch (error) { - console.error({ error }, "getChainId"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); } } - async switchChain(chainId: string): Promise { + // async switchChain(chainId: string): Promise { + // if (!this.provider) + // throw new WalletNotConnectedError({ walletName: this.name }); + // try { + // const fromChainId = await this.getChainId(); + // const toChainId = chainId; + // await this.provider.clearActiveAccount(); + + // if (isNetwork(toChainId)) { + // await this.connect({ chainId: toChainId }); + // } + + // return { + // fromChainId, + // toChainId, + // activeConnector: BeaconConnector.#instance, + // }; + // } catch (error) { + // console.error(error); + // throw new UnknownError({ + // walletName: this.name, + // atFunction: "switchChain", + // }); + // } + // } + + async connect(options?: { chainId: string }): Promise { if (!this.provider) await this.getProvider(); try { - if (!this.provider) throw new Error("Wallet Not Installed"); - await this.connect({ chainId }); - this.chain = chainId; - } catch (error) { - console.error({ error }, "switchChain"); - throw error; - } - } + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); - async connect({ chainId }: { chainId?: string | undefined }): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Installed"); let activeAccount = await this.provider.client.getActiveAccount(); if (!activeAccount) { await this.provider.requestPermissions( - isNetwork(chainId) + options?.chainId && isNetwork(options.chainId) ? { network: { - type: chainId, + type: options.chainId, }, scopes: [PermissionScope.SIGN], } @@ -124,75 +154,84 @@ export class BeaconConnector extends BaseConnector { activeAccount = await this.provider.client.getActiveAccount(); } if (!activeAccount?.address) { - throw new Error("Wallet Not Conencted"); + throw new WalletNotConnectedError({ walletName: this.name }); } - BeaconConnector.publicKey = activeAccount.publicKey; - this.chain = activeAccount.network.type; - setLastUsedConnector(this.name); + const address = activeAccount.address; + const chainId = activeAccount.network.type; + + this.isConnected = true; + this.emitter.emit( + "connected", + address, + chainId, + this.name, + this.ecosystem, + BeaconConnector.#instance + ); + + return { + address, + chainId, + ecosystem: this.ecosystem, + walletName: this.name, + activeConnector: BeaconConnector.#instance, + }; } catch (error) { console.error({ error }, "connect"); throw error; } } - async disconnect(): Promise { - if (!this.provider) await this.getProvider(); + async disconnect(): Promise { + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - if (!this.provider) throw new Error("Wallet Not Installed"); await this.provider.clearActiveAccount(); - BeaconConnector.publicKey = undefined; await this.provider.disconnect(); - } catch (error) { - console.error({ error }, "disconnect"); - throw error; - } - } + this.isConnected = false; - async resolveDid(address: string): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const domain = await fetch( - `https://api.tzkt.io/v1/domains?owner=${address}` - ).then(res => res.json()); - if (!domain || domain.length == 0 || !domain[0]) return null; - return domain[0].name as string; + this.emitter.emit("disconnected", this.name, this.ecosystem); + + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; } catch (error) { - console.error({ error }, "resolveDid"); - throw error; + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); } } - async signMessage(message: string): Promise { - if (!this.provider) await this.getProvider(); + async signMessage(message: string): Promise { + if (!this.provider) + throw new WalletNotConnectedError({ walletName: this.name }); try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const address = await this.provider.getPKH(); + const address = (await this.getAccount())[0]; if (!address) { - throw new Error("Wallet Not Conencted"); + throw new AddressNotFoundError({ walletName: this.name }); } const { signature } = await this.provider.client.requestSignPayload({ signingType: SigningType.MICHELINE, payload: formatMessage(message), sourceAddress: address, }); - return signature; - } catch (error) { - console.error({ error }, "signMessage"); - throw error; - } - } - protected onAccountsChanged(): void { - return; - } + this.emitter.emit("messageSigned", signature, BeaconConnector.#instance); - protected onChainChanged(): void { - return; - } - - protected onDisconnect(): void { - return; + return { + signature, + activeConnector: BeaconConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); + } } } diff --git a/packages/tezos/src/connectors/TempleConnector.ts b/packages/tezos/src/connectors/TempleConnector.ts deleted file mode 100644 index c2791f5..0000000 --- a/packages/tezos/src/connectors/TempleConnector.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { BaseConnector, setLastUsedConnector } from "@wallet01/core"; - -import { TempleDAppNetwork, TempleWallet } from "@temple-wallet/dapp"; -import { TezosToolkit } from "@taquito/taquito"; -import { formatMessage } from "../utils/formatMessage"; -import { isTempleNetwork } from "../utils/isNetwork"; - -interface TempleConnectorOptions { - chain?: string; - rpcUrl?: string; - projectName: string; -} - -export class TempleConnector extends BaseConnector { - provider?: TempleWallet | undefined; - private toolkit: TezosToolkit; - private rpcUrl: string; - private projectName: string; - - static publicKey?: string; - - constructor({ - chain = "mainnet", - projectName, - rpcUrl, - }: TempleConnectorOptions) { - super(chain, "templewallet", "tezos"); - - this.projectName = projectName; - if (rpcUrl) { - this.rpcUrl = rpcUrl; - } else { - this.rpcUrl = "https://mainnet.api.tez.ie/"; - } - - this.toolkit = new TezosToolkit(this.rpcUrl); - this.provider = new TempleWallet(projectName); - - this.toolkit.setProvider({ wallet: this.provider }); - } - - async getProvider(): Promise { - try { - if (this.provider) return this.provider; - const provider = new TempleWallet(this.projectName); - this.provider = provider; - return this.provider; - } catch (error) { - console.error({ error }, "getProvider"); - throw error; - } - } - - async getAccount(): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Installed"); - const account = await this.provider.getPKH(); - if (!account) { - throw new Error("Wallet Not Conencted"); - } - return [account]; - } catch (error) { - console.error({ error }, "getAccount"); - throw error; - } - } - - async getChainId(): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Installed"); - if (!this.chain) await this.connect({}); - return this.chain; - } catch (error) { - console.error({ error }, "getChainId"); - throw error; - } - } - - async switchChain(chainId: string): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Installed"); - await this.provider.reconnect(chainId as TempleDAppNetwork); - this.chain = chainId; - } catch (error) { - console.error({ error }, "switchChain"); - throw error; - } - } - - async connect({ chainId }: { chainId?: string | undefined }): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Provider not initialized"); - - if (!(await TempleWallet.isAvailable())) { - throw new Error("Wallet Not Installed"); - } - - if (isTempleNetwork(chainId)) { - await this.provider.connect(chainId as TempleDAppNetwork); - } else { - await this.provider.connect("mainnet"); - } - - TempleConnector.publicKey = await this.provider.permission?.publicKey; - this.chain = chainId || "mainnet"; - setLastUsedConnector(this.name); - } catch (error) { - console.error({ error }, "connect"); - throw error; - } - } - - async disconnect(): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Installed"); - TempleConnector.publicKey = undefined; - this.provider = undefined; - this.chain = ""; - } catch (error) { - console.error({ error }, "disconnect"); - throw error; - } - } - - async resolveDid(address: string): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const domain = await fetch( - `https://api.tzkt.io/v1/domains?owner=${address}` - ).then(res => res.json()); - if (!domain || domain.length == 0 || !domain[0]) return null; - console.error(address, domain[0].name); - return domain[0].name as string; - } catch (error) { - console.error({ error }, "resolveDid"); - throw error; - } - } - - async signMessage(message: string): Promise { - if (!this.provider) await this.getProvider(); - try { - if (!this.provider) throw new Error("Wallet Not Connected"); - const signature = await this.provider.sign(formatMessage(message)); - return signature; - } catch (error) { - console.error({ error }, "signMessage"); - throw error; - } - } - - protected onAccountsChanged(): void { - return; - } - - protected onChainChanged(_chain: string | number): void { - return; - } - - protected onDisconnect(): void { - return; - } -} diff --git a/packages/tezos/src/index.ts b/packages/tezos/src/index.ts index 0b30333..b4fa4ed 100644 --- a/packages/tezos/src/index.ts +++ b/packages/tezos/src/index.ts @@ -1,4 +1,3 @@ -import { TempleConnector } from "./connectors/TempleConnector"; import { BeaconConnector } from "./connectors/BeaconConnector"; -export { TempleConnector, BeaconConnector }; +export { BeaconConnector }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96aacbb..b7e3d25 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@wallet01/solana': specifier: workspace:* version: link:../../packages/solana + '@wallet01/tezos': + specifier: workspace:* + version: link:../../packages/tezos ethers: specifier: ^5.7.2 version: 5.7.2 @@ -313,14 +316,11 @@ importers: packages/tezos: dependencies: '@taquito/beacon-wallet': - specifier: ^17.1.0 - version: 17.1.0 + specifier: ^17.3.1 + version: 17.3.1 '@taquito/taquito': - specifier: 12.0.0 - version: 12.0.0 - '@temple-wallet/dapp': - specifier: ^7.0.0 - version: 7.0.0(@taquito/taquito@12.0.0) + specifier: ^17.3.1 + version: 17.3.1 '@wallet01/core': specifier: workspace:* version: link:../core @@ -381,11 +381,11 @@ packages: - utf-8-validate dev: false - /@airgap/beacon-core@4.0.2: - resolution: {integrity: sha512-a6mAn6BfbejBQI95tRc6pIZ0VS6MTK9MZ7iXPTLF9hrnCHiROmrCgNKst8qp2dcE0Ehk7z/hGs2WliJzi657YA==} + /@airgap/beacon-core@4.0.10: + resolution: {integrity: sha512-iOAKZRD5BSDFfZKa++FoYBnfDhTLZSzKUbhF/AI6CnnTgzZaEbkTIs+/XVpFhcJQY58hJN77cGnioeG2/WCWkw==} dependencies: - '@airgap/beacon-types': 4.0.2 - '@airgap/beacon-utils': 4.0.2 + '@airgap/beacon-types': 4.0.10 + '@airgap/beacon-utils': 4.0.10 '@stablelib/ed25519': 1.0.3 '@stablelib/nacl': 1.0.4 '@stablelib/utf8': 1.0.1 @@ -393,14 +393,14 @@ packages: bs58check: 2.1.2 dev: false - /@airgap/beacon-dapp@4.0.2: - resolution: {integrity: sha512-7vjvcM470GPfDkizYpuUzJ7Fus7X/zkFeXYTkxx69Dt5TlmKg09YNfRtvrFMDbf4OKnjbaRfVhqzwfYkpaRbPg==} + /@airgap/beacon-dapp@4.0.10: + resolution: {integrity: sha512-QfoRKxMCt4/RjW/lkExicoqzwdhhEhRxPwntS19VW+Q+cWhsJhmWULdF3rQNHRBtSsHws3LnOT0r8e1hndDxfQ==} dependencies: - '@airgap/beacon-core': 4.0.2 - '@airgap/beacon-transport-matrix': 4.0.2 - '@airgap/beacon-transport-postmessage': 4.0.2 - '@airgap/beacon-transport-walletconnect': 4.0.2 - '@airgap/beacon-ui': 4.0.2 + '@airgap/beacon-core': 4.0.10 + '@airgap/beacon-transport-matrix': 4.0.10 + '@airgap/beacon-transport-postmessage': 4.0.10 + '@airgap/beacon-transport-walletconnect': 4.0.10 + '@airgap/beacon-ui': 4.0.10 transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -409,30 +409,30 @@ packages: - utf-8-validate dev: false - /@airgap/beacon-transport-matrix@4.0.2: - resolution: {integrity: sha512-sidXWA9QkcdpTLObsgMIIePq2+6eHn8djSK2UeoAWZpVOky+jpaIU78UlzqgDzMrO9inzu/xwsuXlk5Nmy1RyA==} + /@airgap/beacon-transport-matrix@4.0.10: + resolution: {integrity: sha512-UB7QZaI+hizg5vWYXaGyZfl0uQbhcbJzS6vzyeYxQcUH6uK9h3drHL/UiF8RQuMK73P3WcxShQq1Wn2Pu02gag==} dependencies: - '@airgap/beacon-core': 4.0.2 - '@airgap/beacon-utils': 4.0.2 + '@airgap/beacon-core': 4.0.10 + '@airgap/beacon-utils': 4.0.10 axios: 0.24.0 transitivePeerDependencies: - debug dev: false - /@airgap/beacon-transport-postmessage@4.0.2: - resolution: {integrity: sha512-UDHigcIRD5/VdKX3YDj+CVHYWafYg3N8nHT5yQ2JOU5nsQhD2y5NNNp/7U7I44CcD4OeK9d2slV+lnp8lBYe1g==} + /@airgap/beacon-transport-postmessage@4.0.10: + resolution: {integrity: sha512-MaBRLU/8QFFyXt9LoTN1Vz3dnRwHPptl0r4XPPH6enJTNBZ6PoqLenIs+BiCMMrnMKlBTlRHzfDUlSd9avcFbA==} dependencies: - '@airgap/beacon-core': 4.0.2 - '@airgap/beacon-types': 4.0.2 - '@airgap/beacon-utils': 4.0.2 + '@airgap/beacon-core': 4.0.10 + '@airgap/beacon-types': 4.0.10 + '@airgap/beacon-utils': 4.0.10 dev: false - /@airgap/beacon-transport-walletconnect@4.0.2: - resolution: {integrity: sha512-t4ZrgyImVf8UIhVa6ei/p1STVKNdRq5WSoop8eTSqArIHVj4zk2dr5J0ihbe64UyLAX1O0Z7yV+dUVoH+kVWGw==} + /@airgap/beacon-transport-walletconnect@4.0.10: + resolution: {integrity: sha512-SV9RIZLk6pZVPfEFWWJzB4MuVGi+fBGQsZI25NTPvuT9bvF6IBZwdQp8YwdNiGK3lOhThH+eb82W/b8CH6OOyg==} dependencies: - '@airgap/beacon-core': 4.0.2 - '@airgap/beacon-types': 4.0.2 - '@airgap/beacon-utils': 4.0.2 + '@airgap/beacon-core': 4.0.10 + '@airgap/beacon-types': 4.0.10 + '@airgap/beacon-utils': 4.0.10 '@walletconnect/sign-client': 2.7.0 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -441,25 +441,25 @@ packages: - utf-8-validate dev: false - /@airgap/beacon-types@4.0.2: - resolution: {integrity: sha512-MWbE+350Yd7aICBEwTVIkty/YmKO5eTDsMbReUCNH8qf64gGhj/ZXEN6FPwMab+qKdmACgCkmbbtAXGGtmjwrA==} + /@airgap/beacon-types@4.0.10: + resolution: {integrity: sha512-C7gRyReO1puytL+D9I0xV5WTdbqXtHRcRJHnXt+KTWckZf9eHmUcnAk5JinBlIyFT0oz5jgPxN63UmhJ+lTtZQ==} dependencies: '@types/chrome': 0.0.163 dev: false - /@airgap/beacon-ui@4.0.2: - resolution: {integrity: sha512-ZTcvdQ5GNlQ58M0Fduoq/KqsulBXeBN6jKiHnzHM3e98syy953DKQoDhU2NXNZiJ7AvEGO3s/fd+BN8y/+CVuQ==} + /@airgap/beacon-ui@4.0.10: + resolution: {integrity: sha512-mvhtUSpKfkfz+MWSKXVWHcE8SqD8ChtOv/0dNziQr75LPmLreMB29/hZEQYCfF0T+FXeNVjTvizOlw8sv2Gd6g==} dependencies: - '@airgap/beacon-core': 4.0.2 - '@airgap/beacon-transport-postmessage': 4.0.2 - '@airgap/beacon-types': 4.0.2 - '@airgap/beacon-utils': 4.0.2 + '@airgap/beacon-core': 4.0.10 + '@airgap/beacon-transport-postmessage': 4.0.10 + '@airgap/beacon-types': 4.0.10 + '@airgap/beacon-utils': 4.0.10 qrcode-svg: 1.1.0 solid-js: 1.7.8 dev: false - /@airgap/beacon-utils@4.0.2: - resolution: {integrity: sha512-5TfOI3ZolQQ9WNHogEO3SY4M2Paqbb3hf8DvolFofST6Brp0qyxkwZ0i99puahgwRo+B0qGilZpkLCYl72DMQg==} + /@airgap/beacon-utils@4.0.10: + resolution: {integrity: sha512-g4nCL8hQ2Y59Lp1a0BEm01HbGpjq+WOFFHTD5G3ySTHXwYOIfP1h8T9SLerK2hb91/nMJxthjAshfNwKXaqbqw==} dependencies: '@stablelib/ed25519': 1.0.3 '@stablelib/nacl': 1.0.4 @@ -1987,13 +1987,13 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - /@taquito/beacon-wallet@17.1.0: - resolution: {integrity: sha512-iABiUx4KDXkqXVAKo8W1ik0zEt+aAZRxFHaxtS6wqwmpqCCl9+EGDPpP+FlOLoj320HXlkIba7OdsPpHAEJsKQ==} + /@taquito/beacon-wallet@17.3.1: + resolution: {integrity: sha512-PQDtTZt8rR6yFBM6//3G8KBLW0e9oWqCsHB7WSgk195ShMpHy7bd8eLOWz8ofOBdUFVZ4UDUrR6Pl35Y0HZ/Zw==} engines: {node: '>=16'} dependencies: - '@airgap/beacon-dapp': 4.0.2 - '@taquito/core': 17.1.0 - '@taquito/taquito': 17.1.0 + '@airgap/beacon-dapp': 4.0.10 + '@taquito/core': 17.3.1 + '@taquito/taquito': 17.3.1 transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -2002,167 +2002,86 @@ packages: - utf-8-validate dev: false - /@taquito/core@17.1.0: - resolution: {integrity: sha512-tfdgC7/Q5U9lN3UzvuJYf8Z7iBWyOtqILRuWRGFM6VtSXwNwcNK62f8FNKAgyHahFkVA4vVdD9zrt8NbM/TB2g==} + /@taquito/core@17.3.1: + resolution: {integrity: sha512-dk8ZXuZktfoIV5ESUx3mPkJxLBVL7o3CXLsaVoiPIu2nyd4I/VNkPh+aIOrhxHSVPBib3sVYN0Pc2a8ZO+0gsg==} engines: {node: '>=16'} dev: false - /@taquito/core@17.1.1: - resolution: {integrity: sha512-ib+dzHbVT+0maYGAVdeIk9v9CNkOiB5j8CwnHUygBkEajoOdWTPlsrldRhRTAOnbj+iQk0kdkUECD6KY6iNknw==} + /@taquito/http-utils@17.3.1: + resolution: {integrity: sha512-lHwkNM1sx1HmzJHuxQy3lxaksZH/Jqxq5cYEPJAeCzEj68TD4T4X2rcVPpa0b6Qka5mQgLITCbyFE+RUg+orgA==} engines: {node: '>=16'} - dev: false - - /@taquito/http-utils@12.1.1: - resolution: {integrity: sha512-Zlp/eTRVjFs0XEIiAhgxkh6s9npF4dO+e/Sm2XWsDmNPoGI2jdXNH0L+NiKJIOkYcu0CXlcgriTeEaYnbeTvcA==} - engines: {node: '>=6.0.0'} dependencies: - axios: 0.26.1 - transitivePeerDependencies: - - debug - dev: false - - /@taquito/http-utils@17.1.0: - resolution: {integrity: sha512-vkArbB7h9jMAf6apOERBoUYi/ARiBF5xuJunsPf/hECXz0kjaKGI7dKC6PsWJrvhfR/cACXKu4CAKG41WDNprw==} - engines: {node: '>=16'} - dependencies: - '@taquito/core': 17.1.0 + '@taquito/core': 17.3.1 axios: 0.26.0 transitivePeerDependencies: - debug dev: false - /@taquito/local-forging@12.1.1: - resolution: {integrity: sha512-SUA1YYRIpEGsTy5OfUIgIem0k/QsAzGjDCvf/wl5XV/fVBkP/+GN7uvYoqgJblCmsgtsMBhJFtXgs+D6bjGexg==} - engines: {node: '>=6.0.0'} - dependencies: - '@taquito/utils': 12.1.1 - bignumber.js: 9.1.1 - dev: false - - /@taquito/local-forging@17.1.0: - resolution: {integrity: sha512-vKjjMDoVxgxbjYFhREaNtuI0OT6Jnty6+x+Tfzuk7alLf8zwDBvDXyXz+47WgFZb4Y3RtojRlnpIP4EhbtLnJQ==} + /@taquito/local-forging@17.3.1: + resolution: {integrity: sha512-1pBbN8g2Jhq7bxWW3diRC+llL5TA1/m9W2za75IAl2sv5oo8ttXVla4XY8yapLu/yeOWrb5ta7yvfEZ5x2ZeOw==} engines: {node: '>=16'} dependencies: - '@taquito/core': 17.1.0 - '@taquito/utils': 17.1.1 + '@taquito/core': 17.3.1 + '@taquito/utils': 17.3.1 bignumber.js: 9.1.1 dev: false - /@taquito/michel-codec@12.1.1: - resolution: {integrity: sha512-BAig8YyLyRW5kxV/r0S191W+SvYuiTRJpgSp5IsgCDLAOh+d4/xq6IgU3PuGJgokQDstZdTbjpkrgRCnufR8lw==} - engines: {node: '>=6.0.0'} - dev: false - - /@taquito/michel-codec@17.1.0: - resolution: {integrity: sha512-PjXySJonM77a6uoEOJwGxcz0+1kckahsepMMkjDDdkNhLjTExnNLY5bDoNwzvKj3Ag53zhIWzGwNb4qls1C0XQ==} + /@taquito/michel-codec@17.3.1: + resolution: {integrity: sha512-dxhrqn+/VBzkhL+bhLO9bVb1r/NKdvSYEoXRWgszNT+enVlokkFBM4kXcvGlFUZklaSiw0dQYd1Zk0sDMkr1sw==} engines: {node: '>=16'} dependencies: - '@taquito/core': 17.1.0 - dev: false - - /@taquito/michelson-encoder@12.1.1: - resolution: {integrity: sha512-mWcA1DHHlFj7UswJpEmml853x9e0IYHyeiKZYAo7DtizHz0jiUWtptCuEWiPQ4fMOreFbYZ6KVYenoVfQVNrqA==} - engines: {node: '>=6.0.0'} - dependencies: - '@taquito/rpc': 12.1.1 - '@taquito/utils': 12.1.1 - bignumber.js: 9.1.1 - fast-json-stable-stringify: 2.1.0 - transitivePeerDependencies: - - debug + '@taquito/core': 17.3.1 dev: false - /@taquito/michelson-encoder@17.1.0: - resolution: {integrity: sha512-1sYJp3QENlX2FoT/8poB+CcTH52S5RgIhVM4N0VOWR2MF8+y2SRVjMfrStfC9oDrH4jTt/ESQQFThcyw9XVEMg==} + /@taquito/michelson-encoder@17.3.1: + resolution: {integrity: sha512-PaJYlZnjqDwjvK2qC4j9icqcGLoHHQygnGLs9lPV1quAV1v9yWPe6ABK+miuq2vv4WDMFH6amaXBtLimgPDcuQ==} engines: {node: '>=16'} dependencies: - '@taquito/rpc': 17.1.0 - '@taquito/utils': 17.1.1 + '@taquito/rpc': 17.3.1 + '@taquito/utils': 17.3.1 bignumber.js: 9.1.1 fast-json-stable-stringify: 2.1.0 transitivePeerDependencies: - debug dev: false - /@taquito/rpc@12.1.1: - resolution: {integrity: sha512-CgAF9kdmKLa/UbmiqApDtncCQGiG7kEOIYis8IIa0JUT9JD1H8WBbSNF/oNh4e0soWUK9BL2qU369RFnxIW+iA==} - engines: {node: '>=6.0.0'} - dependencies: - '@taquito/http-utils': 12.1.1 - '@taquito/utils': 12.1.1 - bignumber.js: 9.1.1 - transitivePeerDependencies: - - debug - dev: false - - /@taquito/rpc@17.1.0: - resolution: {integrity: sha512-/nzsGMxHbZOea4C9BnmXGaQVYwERNKF9IwFzdrBVTS7m+lfoRku9QfV88b3K77wXvcpZYSuXa1x4tJIXS8hHXw==} + /@taquito/rpc@17.3.1: + resolution: {integrity: sha512-VHY5qgUVT4RDXDv7H8DQrrMk1tfnJ6m+BFHmJxYCe7WQCCr8u2TlN0X2N95QhM+LG0LXL/LFlzhQLRBOxLnxsw==} engines: {node: '>=16'} dependencies: - '@taquito/core': 17.1.0 - '@taquito/http-utils': 17.1.0 - '@taquito/utils': 17.1.1 + '@taquito/core': 17.3.1 + '@taquito/http-utils': 17.3.1 + '@taquito/utils': 17.3.1 bignumber.js: 9.1.1 transitivePeerDependencies: - debug dev: false - /@taquito/taquito@12.0.0: - resolution: {integrity: sha512-KWKSOCxDW6GG9Hpj50YE35z/l3ISnms90ev8nMICWFdEJd8IHQqj1NQ3/3zCmNn9E/ZLrve3uTHY9RbP7VmeKg==} - engines: {node: '>=6.0.0'} - requiresBuild: true - dependencies: - '@taquito/http-utils': 12.1.1 - '@taquito/local-forging': 12.1.1 - '@taquito/michel-codec': 12.1.1 - '@taquito/michelson-encoder': 12.1.1 - '@taquito/rpc': 12.1.1 - '@taquito/utils': 12.1.1 - bignumber.js: 9.1.1 - rxjs: 6.6.7 - transitivePeerDependencies: - - debug - dev: false - - /@taquito/taquito@17.1.0: - resolution: {integrity: sha512-hmIPgSun3sH40ay1xk4YHR37nhqhjIaRxACZLWkX5vr+N7amFKfPWxUJvI1mlTuT8GFQsVVQMtYMLMs8YOh04Q==} + /@taquito/taquito@17.3.1: + resolution: {integrity: sha512-9CnIJv5z6KmYYhycOSTpSh51hH818yzXMjr5iR4Q2raWEtWQHYeXoDcVec1dkI+IITm9cQpLp5Gm++smSBElOA==} engines: {node: '>=16'} requiresBuild: true dependencies: - '@taquito/core': 17.1.0 - '@taquito/http-utils': 17.1.0 - '@taquito/local-forging': 17.1.0 - '@taquito/michel-codec': 17.1.0 - '@taquito/michelson-encoder': 17.1.0 - '@taquito/rpc': 17.1.0 - '@taquito/utils': 17.1.1 + '@taquito/core': 17.3.1 + '@taquito/http-utils': 17.3.1 + '@taquito/local-forging': 17.3.1 + '@taquito/michel-codec': 17.3.1 + '@taquito/michelson-encoder': 17.3.1 + '@taquito/rpc': 17.3.1 + '@taquito/utils': 17.3.1 bignumber.js: 9.1.1 rxjs: 7.8.1 transitivePeerDependencies: - debug dev: false - /@taquito/utils@12.1.1: - resolution: {integrity: sha512-GxNSBrA02vwhy56ayWB49VZficB+j2oyhPdlsRb2CguephmyEYnlUaNV27ILa6dPDW+zv6+QWQj6GyqLBRpIlA==} - engines: {node: '>=6.0.0'} - dependencies: - '@stablelib/blake2b': 1.0.1 - '@stablelib/ed25519': 1.0.3 - '@types/bs58check': 2.1.0 - blakejs: 1.2.1 - bs58check: 2.1.2 - buffer: 6.0.3 - elliptic: 6.5.4 - typedarray-to-buffer: 4.0.0 - dev: false - - /@taquito/utils@17.1.1: - resolution: {integrity: sha512-KcK7Qa2+SCcevxSJixA3utDtlPYS5DGXpZdMlrAjwjozMiuDGSLM63D1CrW/ojYI0t3tPuErty10cPhURZ+d4A==} + /@taquito/utils@17.3.1: + resolution: {integrity: sha512-NLSFOaZbbs5L7aSV+vgCxj6celHBYLkzwmGvPiCm/mDSj1a1i4bgt8fJ6DbtwDiAmiA9tXPmRileRC4iPEaewg==} engines: {node: '>=16'} dependencies: '@stablelib/blake2b': 1.0.1 '@stablelib/ed25519': 1.0.3 - '@taquito/core': 17.1.1 + '@taquito/core': 17.3.1 '@types/bs58check': 2.1.0 bignumber.js: 9.1.1 blakejs: 1.2.1 @@ -2172,15 +2091,6 @@ packages: typedarray-to-buffer: 4.0.0 dev: false - /@temple-wallet/dapp@7.0.0(@taquito/taquito@12.0.0): - resolution: {integrity: sha512-JbpXompkVDh4Wl0Oa+i8iKEGinFqYPTM4uuqw8eBH57vHxq52W5K3NSgVaKjfyWms9UYQ8xOfsUOzzUVWSYtxA==} - peerDependencies: - '@taquito/taquito': ^12.0.0 - dependencies: - '@taquito/taquito': 12.0.0 - nanoid: 3.3.4 - dev: false - /@types/bs58check@2.1.0: resolution: {integrity: sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==} dependencies: @@ -3016,14 +2926,6 @@ packages: - debug dev: false - /axios@0.26.1: - resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} - dependencies: - follow-redirects: 1.15.2 - transitivePeerDependencies: - - debug - dev: false - /axios@1.3.6: resolution: {integrity: sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==} dependencies: From 365d098ae521cc633d64a5c9aac6db868450d4a6 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 18:56:29 +0530 Subject: [PATCH 11/17] fix: event listeners for wallet events --- package.json | 3 +- packages/core/src/client/client.ts | 2 + packages/core/src/types/BaseConnector.ts | 2 +- packages/evm/package.json | 3 +- packages/evm/src/connectors/coinbase.ts | 23 +++--- packages/evm/src/connectors/injected.ts | 27 ++++--- packages/evm/src/connectors/okxwallet.ts | 24 +++--- packages/solana/src/connectors/phantom.ts | 8 +- packages/solana/src/connectors/solflare.ts | 8 +- pnpm-lock.yaml | 85 +++++++++++++++++++++- 10 files changed, 140 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 231d9c6..efa6027 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "dev": "turbo run dev --parallel", "dev:packages": "turbo run dev --parallel --filter=./packages/*", "lint": "turbo run lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"" + "format": "prettier --write \"**/*.{ts,tsx,md}\"", + "postinstall": "turbo run build --filter=./packages/*" }, "devDependencies": { "@changesets/cli": "^2.25.2", diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index e54548d..2c6d277 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -83,7 +83,9 @@ export default class Wallet01Client { }); this.emitter.on("accountsChanged", addresses => { + console.log("accountsChanged", addresses); this.store.setAddresses(addresses); + if (addresses[0]) this.store.setAddress(addresses[0]); }); } diff --git a/packages/core/src/types/BaseConnector.ts b/packages/core/src/types/BaseConnector.ts index b3f37bd..db1bd1e 100644 --- a/packages/core/src/types/BaseConnector.ts +++ b/packages/core/src/types/BaseConnector.ts @@ -16,7 +16,7 @@ export abstract class BaseConnector< abstract provider: TProvider; readonly name: TWalletName; readonly ecosystem: TEcosystem; - readonly emitter: EnhancedEventEmitter = + protected emitter: EnhancedEventEmitter = EnhancedEventEmitter.init(); constructor(name: TWalletName, ecosystem: TEcosystem) { diff --git a/packages/evm/package.json b/packages/evm/package.json index 4dc67f9..32c61d1 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -21,7 +21,8 @@ "@walletconnect/modal": "^2.5.2", "@web3modal/core": "^2.2.2", "ethers": "^5.7.2", - "eventemitter3": "^4.0.7" + "eventemitter3": "^4.0.7", + "viem": "^1.16.4" }, "devDependencies": { "rimraf": "^3.0.2", diff --git a/packages/evm/src/connectors/coinbase.ts b/packages/evm/src/connectors/coinbase.ts index 4f22b12..efec765 100644 --- a/packages/evm/src/connectors/coinbase.ts +++ b/packages/evm/src/connectors/coinbase.ts @@ -151,9 +151,9 @@ export class CoinbaseConnector extends BaseConnector< throw new UserRejectedRequestError(); } - this.provider.on("accountsChanged", this.onAccountsChanged); - this.provider.on("disconnect", this.onDisconnect); - this.provider.on("chainChanged", this.onChainChanged); + this.provider.on("accountsChanged", this._onAccountsChanged); + this.provider.on("disconnect", this._onDisconnect); + this.provider.on("chainChanged", this._onChainChanged); const currentId = await this.getChainId(); if (options?.chainId && currentId !== options.chainId) { @@ -192,6 +192,11 @@ export class CoinbaseConnector extends BaseConnector< try { await this.provider.disconnect(); this.emitter.emit("disconnected", this.name, this.ecosystem); + + this.provider.removeListener("accountsChanged", this._onAccountsChanged); + this.provider.removeListener("disconnect", this._onDisconnect); + this.provider.removeListener("chainChanged", this._onChainChanged); + return { walletName: this.name, ecosystem: this.ecosystem, @@ -242,19 +247,19 @@ export class CoinbaseConnector extends BaseConnector< } } - protected onAccountsChanged(accounts: string[]): void { + protected _onAccountsChanged = (accounts: string[]) => { this.emitter.emit("accountsChanged", accounts, CoinbaseConnector.#instance); - } + }; - protected onChainChanged(hexChainId: string): void { + protected _onChainChanged = (hexChainId: string) => { const chainId = parseInt(hexChainId, 16).toString(); this.emitter.emit("chainChanged", chainId, CoinbaseConnector.#instance); - } + }; - protected onDisconnect(error: any): void { + protected _onDisconnect = (error: any) => { console.error({ error, }); this.emitter.emit("disconnected", this.name, this.ecosystem); - } + }; } diff --git a/packages/evm/src/connectors/injected.ts b/packages/evm/src/connectors/injected.ts index 89ea46e..56e300a 100644 --- a/packages/evm/src/connectors/injected.ts +++ b/packages/evm/src/connectors/injected.ts @@ -157,9 +157,9 @@ export class InjectedConnector extends BaseConnector { throw new UserRejectedRequestError(); } - this.provider.on("accountsChanged", this.onAccountsChanged); - this.provider.on("disconnect", this.onDisconnect); - this.provider.on("chainChanged", this.onChainChanged); + window.ethereum.on("accountsChanged", this._onAccountsChanged); + window.ethereum.on("disconnect", this._onDisconnect); + window.ethereum.on("chainChanged", this._onChainChanged); const currentId = await this.getChainId(); if (options?.chainId && currentId !== options.chainId) { @@ -199,9 +199,12 @@ export class InjectedConnector extends BaseConnector { if (!this.provider) throw new ProviderNotFoundError({ walletName: this.name }); - this.provider.removeListener("accountsChanged", this.onAccountsChanged); - this.provider.removeListener("chainChanged", this.onChainChanged); - this.provider.removeListener("disconnect", this.onDisconnect); + window.ethereum.removeListener( + "accountsChanged", + this._onAccountsChanged + ); + window.ethereum.removeListener("chainChanged", this._onChainChanged); + window.ethereum.removeListener("disconnect", this._onDisconnect); this.emitter.emit("disconnected", this.name, this.ecosystem); return { @@ -254,19 +257,19 @@ export class InjectedConnector extends BaseConnector { } } - protected onAccountsChanged(accounts: string[]): void { + protected _onAccountsChanged = (accounts: string[]) => { this.emitter.emit("accountsChanged", accounts, InjectedConnector.#instance); - } + }; - protected onChainChanged(hexChainId: string): void { + protected _onChainChanged = (hexChainId: string) => { const chainId = parseInt(hexChainId, 16).toString(); this.emitter.emit("chainChanged", chainId, InjectedConnector.#instance); - } + }; - protected onDisconnect(error: any): void { + protected _onDisconnect = (error: any) => { console.error({ error, }); this.emitter.emit("disconnected", this.name, this.ecosystem); - } + }; } diff --git a/packages/evm/src/connectors/okxwallet.ts b/packages/evm/src/connectors/okxwallet.ts index 55a384d..1309eca 100644 --- a/packages/evm/src/connectors/okxwallet.ts +++ b/packages/evm/src/connectors/okxwallet.ts @@ -154,9 +154,9 @@ export class OkxWalletConnector extends BaseConnector { throw new UserRejectedRequestError(); } - this.provider.on("accountsChanged", this.onAccountsChanged); - this.provider.on("disconnect", this.onDisconnect); - this.provider.on("chainChanged", this.onChainChanged); + this.provider.on("accountsChanged", this._onAccountsChanged); + this.provider.on("disconnect", this._onDisconnect); + this.provider.on("chainChanged", this._onChainChanged); const currentId = await this.getChainId(); if (options?.chainId && currentId !== options.chainId) { @@ -196,9 +196,9 @@ export class OkxWalletConnector extends BaseConnector { if (!this.provider) throw new ProviderNotFoundError({ walletName: this.name }); - this.provider.removeListener("accountsChanged", this.onAccountsChanged); - this.provider.removeListener("chainChanged", this.onChainChanged); - this.provider.removeListener("disconnect", this.onDisconnect); + this.provider.removeListener("accountsChanged", this._onAccountsChanged); + this.provider.removeListener("chainChanged", this._onChainChanged); + this.provider.removeListener("disconnect", this._onDisconnect); this.emitter.emit("disconnected", this.name, this.ecosystem); return { @@ -251,23 +251,23 @@ export class OkxWalletConnector extends BaseConnector { } } - protected onAccountsChanged(accounts: string[]): void { + protected _onAccountsChanged = (accounts: string[]) => { this.emitter.emit( "accountsChanged", accounts, OkxWalletConnector.#instance ); - } + }; - protected onChainChanged(hexChainId: string): void { + protected _onChainChanged = (hexChainId: string) => { const chainId = parseInt(hexChainId, 16).toString(); this.emitter.emit("chainChanged", chainId, OkxWalletConnector.#instance); - } + }; - protected onDisconnect(error: any): void { + protected _onDisconnect = (error: any) => { console.error({ error, }); this.emitter.emit("disconnected", this.name, this.ecosystem); - } + }; } diff --git a/packages/solana/src/connectors/phantom.ts b/packages/solana/src/connectors/phantom.ts index 17cb162..a9d7d88 100644 --- a/packages/solana/src/connectors/phantom.ts +++ b/packages/solana/src/connectors/phantom.ts @@ -137,12 +137,12 @@ export class PhantomConnector extends BaseConnector { } } - protected onAccountsChanged(accounts: string[]): void { + protected onAccountsChanged = (accounts: string[]) => { this.emitter.emit("accountsChanged", accounts, PhantomConnector.#instance); - } + }; - protected onDisconnect(error: any): void { + protected onDisconnect = (error: any) => { console.error(error); this.emitter.emit("disconnected", this.name, this.ecosystem); - } + }; } diff --git a/packages/solana/src/connectors/solflare.ts b/packages/solana/src/connectors/solflare.ts index 8fef87b..2526055 100644 --- a/packages/solana/src/connectors/solflare.ts +++ b/packages/solana/src/connectors/solflare.ts @@ -136,15 +136,15 @@ export class SolflareConnector extends BaseConnector { } } - protected onAccountsChanged(address: string): void { + protected onAccountsChanged = (address: string) => { this.emitter.emit( "accountsChanged", [address], SolflareConnector.#instance ); - } + }; - protected onDisconnect(): void { + protected onDisconnect = () => { this.emitter.emit("disconnected", this.name, this.ecosystem); - } + }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7e3d25..9a2fb4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -240,6 +240,9 @@ importers: eventemitter3: specifier: ^4.0.7 version: 4.0.7 + viem: + specifier: ^1.16.4 + version: 1.16.4(typescript@4.9.4) devDependencies: rimraf: specifier: ^3.0.2 @@ -381,6 +384,10 @@ packages: - utf-8-validate dev: false + /@adraffy/ens-normalize@1.9.4: + resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} + dev: false + /@airgap/beacon-core@4.0.10: resolution: {integrity: sha512-iOAKZRD5BSDFfZKa++FoYBnfDhTLZSzKUbhF/AI6CnnTgzZaEbkTIs+/XVpFhcJQY58hJN77cGnioeG2/WCWkw==} dependencies: @@ -1727,6 +1734,25 @@ packages: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true + /@scure/base@1.1.3: + resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + dev: false + + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false + + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false + /@solana/buffer-layout@4.0.0: resolution: {integrity: sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==} engines: {node: '>=5.10'} @@ -2670,6 +2696,20 @@ packages: through: 2.3.8 dev: false + /abitype@0.9.8(typescript@4.9.4): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 4.9.4 + dev: false + /acorn-jsx@5.3.2(acorn@7.4.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5017,6 +5057,14 @@ packages: ws: 7.5.9 dev: false + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + /jayson@3.7.0: resolution: {integrity: sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ==} engines: {node: '>=8'} @@ -6975,7 +7023,6 @@ packages: /typescript@4.9.4: resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} - dev: true /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} @@ -7093,6 +7140,29 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false + /viem@1.16.4(typescript@4.9.4): + resolution: {integrity: sha512-T9ziN3EERXz0BtQSS2VJM+P1EJ2W7K7PviobFrmvWCEYmNQ/vJDhfFqGjvq0ZL9LVz9HvevCbenEy8oIdMEZ+w==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.9.4 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@4.9.4) + isows: 1.0.3(ws@8.13.0) + typescript: 4.9.4 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + /vite@3.2.4: resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7266,6 +7336,19 @@ packages: utf-8-validate: 5.0.10 dev: false + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} From 7782bf2b1b16e63c64cd6f4102dc8738bb56d5aa Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 12 Oct 2023 19:03:44 +0530 Subject: [PATCH 12/17] chore: updating changeset/cli --- package.json | 2 +- pnpm-lock.yaml | 171 ++++++++++++++++++++++++++----------------------- 2 files changed, 93 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index efa6027..2e6214b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "postinstall": "turbo run build --filter=./packages/*" }, "devDependencies": { - "@changesets/cli": "^2.25.2", + "@changesets/cli": "^2.26.2", "eslint-config-custom": "workspace:*", "prettier": "latest", "turbo": "latest" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a2fb4c..178378d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.25.2 - version: 2.25.2 + specifier: ^2.26.2 + version: 2.26.2 eslint-config-custom: specifier: workspace:* version: link:configs/eslint @@ -728,7 +728,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 - dev: false /@babel/template@7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} @@ -766,14 +765,14 @@ packages: to-fast-properties: 2.0.0 dev: true - /@changesets/apply-release-plan@6.1.2: - resolution: {integrity: sha512-H8TV9E/WtJsDfoDVbrDGPXmkZFSv7W2KLqp4xX4MKZXshb0hsQZUNowUa8pnus9qb/5OZrFFRVsUsDCVHNW/AQ==} + /@changesets/apply-release-plan@6.1.4: + resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} dependencies: - '@babel/runtime': 7.20.1 - '@changesets/config': 2.2.0 + '@babel/runtime': 7.23.2 + '@changesets/config': 2.3.1 '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 1.5.0 - '@changesets/types': 5.2.0 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -781,46 +780,47 @@ packages: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 5.7.1 + semver: 7.5.4 dev: true - /@changesets/assemble-release-plan@5.2.2: - resolution: {integrity: sha512-B1qxErQd85AeZgZFZw2bDKyOfdXHhG+X5S+W3Da2yCem8l/pRy4G/S7iOpEcMwg6lH8q2ZhgbZZwZ817D+aLuQ==} + /@changesets/assemble-release-plan@5.2.4: + resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/types': 5.2.0 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 - semver: 5.7.1 + semver: 7.5.4 dev: true - /@changesets/changelog-git@0.1.13: - resolution: {integrity: sha512-zvJ50Q+EUALzeawAxax6nF2WIcSsC5PwbuLeWkckS8ulWnuPYx8Fn/Sjd3rF46OzeKA8t30loYYV6TIzp4DIdg==} + /@changesets/changelog-git@0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 dev: true - /@changesets/cli@2.25.2: - resolution: {integrity: sha512-ACScBJXI3kRyMd2R8n8SzfttDHi4tmKSwVwXBazJOylQItSRSF4cGmej2E4FVf/eNfGy6THkL9GzAahU9ErZrA==} + /@changesets/cli@2.26.2: + resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} + hasBin: true dependencies: - '@babel/runtime': 7.20.1 - '@changesets/apply-release-plan': 6.1.2 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/changelog-git': 0.1.13 - '@changesets/config': 2.2.0 + '@babel/runtime': 7.23.2 + '@changesets/apply-release-plan': 6.1.4 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/changelog-git': 0.1.14 + '@changesets/config': 2.3.1 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/get-release-plan': 3.0.15 - '@changesets/git': 1.5.0 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/get-release-plan': 3.0.17 + '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 - '@changesets/write': 0.2.2 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@changesets/write': 0.2.3 '@manypkg/get-packages': 1.1.3 '@types/is-ci': 3.0.0 - '@types/semver': 6.2.3 + '@types/semver': 7.5.3 ansi-colors: 4.1.3 chalk: 2.4.2 enquirer: 2.3.6 @@ -833,19 +833,19 @@ packages: p-limit: 2.3.0 preferred-pm: 3.0.3 resolve-from: 5.0.0 - semver: 5.7.1 + semver: 7.5.4 spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 4.1.6 dev: true - /@changesets/config@2.2.0: - resolution: {integrity: sha512-GGaokp3nm5FEDk/Fv2PCRcQCOxGKKPRZ7prcMqxEr7VSsG75MnChQE8plaW1k6V8L2bJE+jZWiRm19LbnproOw==} + /@changesets/config@2.3.1: + resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} dependencies: '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 + '@changesets/get-dependents-graph': 1.3.6 '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 @@ -857,25 +857,25 @@ packages: extendable-error: 0.1.7 dev: true - /@changesets/get-dependents-graph@1.3.4: - resolution: {integrity: sha512-+C4AOrrFY146ydrgKOo5vTZfj7vetNu1tWshOID+UjPUU9afYGDXI8yLnAeib1ffeBXV3TuGVcyphKpJ3cKe+A==} + /@changesets/get-dependents-graph@1.3.6: + resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 5.7.1 + semver: 7.5.4 dev: true - /@changesets/get-release-plan@3.0.15: - resolution: {integrity: sha512-W1tFwxE178/en+zSj/Nqbc3mvz88mcdqUMJhRzN1jDYqN3QI4ifVaRF9mcWUU+KI0gyYEtYR65tour690PqTcA==} + /@changesets/get-release-plan@3.0.17: + resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} dependencies: - '@babel/runtime': 7.20.1 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/config': 2.2.0 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 + '@babel/runtime': 7.23.2 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/config': 2.3.1 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 dev: true @@ -883,14 +883,15 @@ packages: resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} dev: true - /@changesets/git@1.5.0: - resolution: {integrity: sha512-Xo8AT2G7rQJSwV87c8PwMm6BAc98BnufRMsML7m7Iw8Or18WFvFmxqG5aOL5PBvhgq9KrKvaeIBNIymracSuHg==} + /@changesets/git@2.0.0: + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 + micromatch: 4.0.5 spawndamnit: 2.0.0 dev: true @@ -900,31 +901,31 @@ packages: chalk: 2.4.2 dev: true - /@changesets/parse@0.3.15: - resolution: {integrity: sha512-3eDVqVuBtp63i+BxEWHPFj2P1s3syk0PTrk2d94W9JD30iG+OER0Y6n65TeLlY8T2yB9Fvj6Ev5Gg0+cKe/ZUA==} + /@changesets/parse@0.3.16: + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 js-yaml: 3.14.1 dev: true - /@changesets/pre@1.0.13: - resolution: {integrity: sha512-jrZc766+kGZHDukjKhpBXhBJjVQMied4Fu076y9guY1D3H622NOw8AQaLV3oQsDtKBTrT2AUFjt9Z2Y9Qx+GfA==} + /@changesets/pre@1.0.14: + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 dev: true - /@changesets/read@0.5.8: - resolution: {integrity: sha512-eYaNfxemgX7f7ELC58e7yqQICW5FB7V+bd1lKt7g57mxUrTveYME+JPaBPpYx02nP53XI6CQp6YxnR9NfmFPKw==} + /@changesets/read@0.5.9: + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} dependencies: - '@babel/runtime': 7.20.1 - '@changesets/git': 1.5.0 + '@babel/runtime': 7.23.2 + '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.15 - '@changesets/types': 5.2.0 + '@changesets/parse': 0.3.16 + '@changesets/types': 5.2.1 chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -934,15 +935,15 @@ packages: resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} dev: true - /@changesets/types@5.2.0: - resolution: {integrity: sha512-km/66KOqJC+eicZXsm2oq8A8bVTSpkZJ60iPV/Nl5Z5c7p9kk8xxh6XGRTlnludHldxOOfudhnDN2qPxtHmXzA==} + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} dev: true - /@changesets/write@0.2.2: - resolution: {integrity: sha512-kCYNHyF3xaId1Q/QE+DF3UTrHTyg3Cj/f++T8S8/EkC+jh1uK2LFnM9h+EzV+fsmnZDrs7r0J4LLpeI/VWC5Hg==} + /@changesets/write@0.2.3: + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} dependencies: - '@babel/runtime': 7.20.1 - '@changesets/types': 5.2.0 + '@babel/runtime': 7.23.2 + '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 2.8.8 @@ -1436,7 +1437,7 @@ packages: /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.23.2 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -1445,7 +1446,7 @@ packages: /@manypkg/get-packages@1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.23.2 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -2216,8 +2217,8 @@ packages: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} dev: true - /@types/semver@6.2.3: - resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} + /@types/semver@7.5.3: + resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==} dev: true /@types/trusted-types@2.0.3: @@ -4919,6 +4920,7 @@ packages: /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true dependencies: ci-info: 3.7.0 dev: true @@ -6223,7 +6225,6 @@ packages: /regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} - dev: false /regexp.prototype.flags@1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} @@ -6385,6 +6386,7 @@ packages: /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true dev: true /semver@6.3.0: @@ -6397,6 +6399,14 @@ packages: dependencies: lru-cache: 6.0.0 + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /seroval@0.5.1: resolution: {integrity: sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==} engines: {node: '>=10'} @@ -6462,6 +6472,7 @@ packages: /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} + hasBin: true dependencies: array.prototype.flat: 1.3.1 breakword: 1.0.5 @@ -6911,6 +6922,7 @@ packages: /tty-table@4.1.6: resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} engines: {node: '>=8.0.0'} + hasBin: true dependencies: chalk: 4.1.2 csv: 5.5.3 @@ -7260,6 +7272,7 @@ packages: /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true dependencies: isexe: 2.0.0 dev: true From afb987d10c645e5c57e3c9395737301b938565e2 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Tue, 17 Oct 2023 12:54:14 +0530 Subject: [PATCH 13/17] add: changeset beta publish --- .changeset/happy-schools-add.md | 10 ++++++++++ .changeset/pre.json | 19 +++++++++++++++++++ examples/vite-react/CHANGELOG.md | 10 ++++++++++ examples/vite-react/package.json | 2 +- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- packages/cosmos/CHANGELOG.md | 11 +++++++++++ packages/cosmos/package.json | 2 +- packages/evm/CHANGELOG.md | 11 +++++++++++ packages/evm/package.json | 2 +- packages/react/CHANGELOG.md | 11 +++++++++++ packages/react/package.json | 2 +- packages/solana/CHANGELOG.md | 11 +++++++++++ packages/solana/package.json | 2 +- packages/tezos/CHANGELOG.md | 11 +++++++++++ packages/tezos/package.json | 2 +- 16 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 .changeset/happy-schools-add.md create mode 100644 .changeset/pre.json diff --git a/.changeset/happy-schools-add.md b/.changeset/happy-schools-add.md new file mode 100644 index 0000000..e8b4719 --- /dev/null +++ b/.changeset/happy-schools-add.md @@ -0,0 +1,10 @@ +--- +"@wallet01/react": major +"@wallet01/core": major +"@wallet01/cosmos": minor +"@wallet01/solana": minor +"@wallet01/tezos": minor +"@wallet01/evm": minor +--- + +New events based architecture Wallet01; updated connectors and react package diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000..812633c --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,19 @@ +{ + "mode": "pre", + "tag": "beta", + "initialVersions": { + "eslint-config-custom": "0.0.0", + "tsconfig": "0.0.0", + "example-nextjs": "0.1.40-beta.4", + "exmaple-vite-react": "0.0.41", + "@wallet01/core": "0.6.5", + "@wallet01/cosmos": "0.7.5", + "@wallet01/evm": "0.11.1", + "@wallet01/react": "0.8.7", + "@wallet01/solana": "0.6.6", + "@wallet01/tezos": "0.2.1" + }, + "changesets": [ + "happy-schools-add" + ] +} diff --git a/examples/vite-react/CHANGELOG.md b/examples/vite-react/CHANGELOG.md index 04711b7..5d1814c 100644 --- a/examples/vite-react/CHANGELOG.md +++ b/examples/vite-react/CHANGELOG.md @@ -1,5 +1,15 @@ # vite-react +## 0.0.42-beta.0 + +### Patch Changes + +- Updated dependencies + - @wallet01/react@1.0.0-beta.0 + - @wallet01/cosmos@0.8.0-beta.0 + - @wallet01/solana@0.7.0-beta.0 + - @wallet01/evm@0.12.0-beta.0 + ## 0.0.41 ### Patch Changes diff --git a/examples/vite-react/package.json b/examples/vite-react/package.json index 3a5f787..6ec66cc 100644 --- a/examples/vite-react/package.json +++ b/examples/vite-react/package.json @@ -1,7 +1,7 @@ { "name": "exmaple-vite-react", "private": true, - "version": "0.0.41", + "version": "0.0.42-beta.0", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 78566aa..3c8e4ac 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @wallet01/core +## 1.0.0-beta.0 + +### Major Changes + +- New events based architecture Wallet01; updated connectors and react package + ## 0.6.5 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 83701c9..2d95295 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/core", - "version": "0.6.5", + "version": "1.0.0-beta.0", "description": "", "main": "dist/index.cjs", "types": "dist/index.d.ts", diff --git a/packages/cosmos/CHANGELOG.md b/packages/cosmos/CHANGELOG.md index 790a97f..1c58108 100644 --- a/packages/cosmos/CHANGELOG.md +++ b/packages/cosmos/CHANGELOG.md @@ -1,5 +1,16 @@ # @wallet01/cosmos +## 0.8.0-beta.0 + +### Minor Changes + +- New events based architecture Wallet01; updated connectors and react package + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.0 + ## 0.7.5 ### Patch Changes diff --git a/packages/cosmos/package.json b/packages/cosmos/package.json index 4908d04..bd2221d 100644 --- a/packages/cosmos/package.json +++ b/packages/cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/cosmos", - "version": "0.7.5", + "version": "0.8.0-beta.0", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/evm/CHANGELOG.md b/packages/evm/CHANGELOG.md index fb8c1f6..7c16d4b 100644 --- a/packages/evm/CHANGELOG.md +++ b/packages/evm/CHANGELOG.md @@ -1,5 +1,16 @@ # @wallet01/evm +## 0.12.0-beta.0 + +### Minor Changes + +- New events based architecture Wallet01; updated connectors and react package + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.0 + ## 0.11.1 ### Patch Changes diff --git a/packages/evm/package.json b/packages/evm/package.json index 32c61d1..e4630c4 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/evm", - "version": "0.11.1", + "version": "0.12.0-beta.0", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 8802e0b..a7fd1b0 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,16 @@ # @wallet01/react +## 1.0.0-beta.0 + +### Major Changes + +- New events based architecture Wallet01; updated connectors and react package + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.0 + ## 0.8.7 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 96e7208..d577d98 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/react", - "version": "0.8.7", + "version": "1.0.0-beta.0", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/solana/CHANGELOG.md b/packages/solana/CHANGELOG.md index 448bad4..fc7d3e3 100644 --- a/packages/solana/CHANGELOG.md +++ b/packages/solana/CHANGELOG.md @@ -1,5 +1,16 @@ # @wallet01/solana +## 0.7.0-beta.0 + +### Minor Changes + +- New events based architecture Wallet01; updated connectors and react package + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.0 + ## 0.6.6 ### Patch Changes diff --git a/packages/solana/package.json b/packages/solana/package.json index 7140637..39c56f9 100644 --- a/packages/solana/package.json +++ b/packages/solana/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/solana", - "version": "0.6.6", + "version": "0.7.0-beta.0", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/tezos/CHANGELOG.md b/packages/tezos/CHANGELOG.md index b97f228..f531097 100644 --- a/packages/tezos/CHANGELOG.md +++ b/packages/tezos/CHANGELOG.md @@ -1,5 +1,16 @@ # @wallet01/tezos +## 0.3.0-beta.0 + +### Minor Changes + +- New events based architecture Wallet01; updated connectors and react package + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.0 + ## 0.2.1 ### Patch Changes diff --git a/packages/tezos/package.json b/packages/tezos/package.json index dcd5b88..03c1c30 100644 --- a/packages/tezos/package.json +++ b/packages/tezos/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/tezos", - "version": "0.2.1", + "version": "0.3.0-beta.0", "description": "", "main": "dist/index.js", "types": "dist/index.d.ts", From 82d86931474243f3388a03876d1efc23371242f2 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Tue, 17 Oct 2023 13:05:53 +0530 Subject: [PATCH 14/17] add: isAutoConnecting variable --- .changeset/friendly-bobcats-repeat.md | 6 ++++++ .changeset/happy-gifts-tap.md | 5 +++++ .changeset/pre.json | 1 + examples/vite-react/CHANGELOG.md | 10 ++++++++++ examples/vite-react/package.json | 2 +- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- packages/core/src/client/client.ts | 10 +++++++++- packages/core/src/client/store.ts | 10 ++++++++++ packages/core/src/store/createClientSlice.ts | 4 ++++ packages/core/src/store/storeTypes.ts | 2 ++ packages/cosmos/CHANGELOG.md | 7 +++++++ packages/cosmos/package.json | 2 +- packages/evm/CHANGELOG.md | 7 +++++++ packages/evm/package.json | 2 +- packages/react/CHANGELOG.md | 8 ++++++++ packages/react/package.json | 2 +- packages/react/src/hooks/useClient.ts | 4 +++- packages/solana/CHANGELOG.md | 7 +++++++ packages/solana/package.json | 2 +- packages/tezos/CHANGELOG.md | 7 +++++++ packages/tezos/package.json | 2 +- 22 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 .changeset/friendly-bobcats-repeat.md create mode 100644 .changeset/happy-gifts-tap.md diff --git a/.changeset/friendly-bobcats-repeat.md b/.changeset/friendly-bobcats-repeat.md new file mode 100644 index 0000000..91d574d --- /dev/null +++ b/.changeset/friendly-bobcats-repeat.md @@ -0,0 +1,6 @@ +--- +"@wallet01/react": patch +"@wallet01/core": patch +--- + +adding isAutoConnecting variable diff --git a/.changeset/happy-gifts-tap.md b/.changeset/happy-gifts-tap.md new file mode 100644 index 0000000..667223d --- /dev/null +++ b/.changeset/happy-gifts-tap.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +build then publish diff --git a/.changeset/pre.json b/.changeset/pre.json index 812633c..9c160c4 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -14,6 +14,7 @@ "@wallet01/tezos": "0.2.1" }, "changesets": [ + "friendly-bobcats-repeat", "happy-schools-add" ] } diff --git a/examples/vite-react/CHANGELOG.md b/examples/vite-react/CHANGELOG.md index 5d1814c..992806b 100644 --- a/examples/vite-react/CHANGELOG.md +++ b/examples/vite-react/CHANGELOG.md @@ -1,5 +1,15 @@ # vite-react +## 0.0.42-beta.1 + +### Patch Changes + +- Updated dependencies + - @wallet01/react@1.0.0-beta.1 + - @wallet01/cosmos@0.8.0-beta.1 + - @wallet01/evm@0.12.0-beta.1 + - @wallet01/solana@0.7.0-beta.1 + ## 0.0.42-beta.0 ### Patch Changes diff --git a/examples/vite-react/package.json b/examples/vite-react/package.json index 6ec66cc..d42aa48 100644 --- a/examples/vite-react/package.json +++ b/examples/vite-react/package.json @@ -1,7 +1,7 @@ { "name": "exmaple-vite-react", "private": true, - "version": "0.0.42-beta.0", + "version": "0.0.42-beta.1", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 3c8e4ac..cc80573 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @wallet01/core +## 1.0.0-beta.1 + +### Patch Changes + +- adding isAutoConnecting variable + ## 1.0.0-beta.0 ### Major Changes diff --git a/packages/core/package.json b/packages/core/package.json index 2d95295..7ba27d3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/core", - "version": "1.0.0-beta.0", + "version": "1.0.0-beta.1", "description": "", "main": "dist/index.cjs", "types": "dist/index.d.ts", diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index 2c6d277..37ab49c 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -121,7 +121,15 @@ export default class Wallet01Client { activeConnector ); - await activeConnector.connect(); + this.store.setIsAutoConnecting(true); + await activeConnector + .connect() + .then(() => { + this.store.setIsAutoConnecting(false); + }) + .catch(() => { + this.store.setIsAutoConnecting(false); + }); } } } diff --git a/packages/core/src/client/store.ts b/packages/core/src/client/store.ts index b0199d7..b1af524 100644 --- a/packages/core/src/client/store.ts +++ b/packages/core/src/client/store.ts @@ -23,6 +23,11 @@ export class Wallet01Store { return ecosystem; } + getIsAutoConnecting() { + const { isAutoConnecting } = getState(); + return isAutoConnecting; + } + getAddress() { const { address } = getState(); return address; @@ -58,6 +63,11 @@ export class Wallet01Store { setEcosystem(ecosystem); } + setIsAutoConnecting(val: boolean) { + const { setAutoConnecting } = getState(); + setAutoConnecting(val); + } + setAddress(address: string | null) { const { setAddress } = getState(); setAddress(address); diff --git a/packages/core/src/store/createClientSlice.ts b/packages/core/src/store/createClientSlice.ts index 52a628f..89f21a9 100644 --- a/packages/core/src/store/createClientSlice.ts +++ b/packages/core/src/store/createClientSlice.ts @@ -7,9 +7,13 @@ const createClientSlice: StateCreator< [], IClientState > = set => ({ + isAutoConnecting: false, ecosystem: null, connectors: [], activeConnector: null, + setAutoConnecting: val => { + set(() => ({ isAutoConnecting: val })); + }, setEcosystem: ecosystem => { set(() => ({ ecosystem })); }, diff --git a/packages/core/src/store/storeTypes.ts b/packages/core/src/store/storeTypes.ts index b6708b1..53dadd0 100644 --- a/packages/core/src/store/storeTypes.ts +++ b/packages/core/src/store/storeTypes.ts @@ -17,9 +17,11 @@ export interface IWalletState { } export interface IClientState { + isAutoConnecting: boolean; ecosystem: TEcosystem | null; connectors: BaseConnector[]; activeConnector: BaseConnector | null; + setAutoConnecting: (val: boolean) => void; setEcosystem: (val: TEcosystem | null) => void; setConnectors: (connectors: BaseConnector[]) => void; setActiveConnector: (connector: BaseConnector | null) => void; diff --git a/packages/cosmos/CHANGELOG.md b/packages/cosmos/CHANGELOG.md index 1c58108..7c3a0ea 100644 --- a/packages/cosmos/CHANGELOG.md +++ b/packages/cosmos/CHANGELOG.md @@ -1,5 +1,12 @@ # @wallet01/cosmos +## 0.8.0-beta.1 + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.1 + ## 0.8.0-beta.0 ### Minor Changes diff --git a/packages/cosmos/package.json b/packages/cosmos/package.json index bd2221d..6f2e6d6 100644 --- a/packages/cosmos/package.json +++ b/packages/cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/cosmos", - "version": "0.8.0-beta.0", + "version": "0.8.0-beta.1", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/evm/CHANGELOG.md b/packages/evm/CHANGELOG.md index 7c16d4b..1a3bed4 100644 --- a/packages/evm/CHANGELOG.md +++ b/packages/evm/CHANGELOG.md @@ -1,5 +1,12 @@ # @wallet01/evm +## 0.12.0-beta.1 + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.1 + ## 0.12.0-beta.0 ### Minor Changes diff --git a/packages/evm/package.json b/packages/evm/package.json index e4630c4..e1e275d 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/evm", - "version": "0.12.0-beta.0", + "version": "0.12.0-beta.1", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index a7fd1b0..d8c94d0 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @wallet01/react +## 1.0.0-beta.1 + +### Patch Changes + +- adding isAutoConnecting variable +- Updated dependencies + - @wallet01/core@1.0.0-beta.1 + ## 1.0.0-beta.0 ### Major Changes diff --git a/packages/react/package.json b/packages/react/package.json index d577d98..8060326 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/react", - "version": "1.0.0-beta.0", + "version": "1.0.0-beta.2", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/react/src/hooks/useClient.ts b/packages/react/src/hooks/useClient.ts index 78c3d24..ec7a7e3 100644 --- a/packages/react/src/hooks/useClient.ts +++ b/packages/react/src/hooks/useClient.ts @@ -1,11 +1,13 @@ import { useStore } from "@wallet01/core"; export const useClient = () => { - const { connectors, ecosystem, activeConnector } = useStore(); + const { connectors, ecosystem, activeConnector, isAutoConnecting } = + useStore(); return { connectors, ecosystem, activeConnector, + isAutoConnecting, }; }; diff --git a/packages/solana/CHANGELOG.md b/packages/solana/CHANGELOG.md index fc7d3e3..636cb59 100644 --- a/packages/solana/CHANGELOG.md +++ b/packages/solana/CHANGELOG.md @@ -1,5 +1,12 @@ # @wallet01/solana +## 0.7.0-beta.1 + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.1 + ## 0.7.0-beta.0 ### Minor Changes diff --git a/packages/solana/package.json b/packages/solana/package.json index 39c56f9..ba49dd7 100644 --- a/packages/solana/package.json +++ b/packages/solana/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/solana", - "version": "0.7.0-beta.0", + "version": "0.7.0-beta.1", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/tezos/CHANGELOG.md b/packages/tezos/CHANGELOG.md index f531097..6a98b0b 100644 --- a/packages/tezos/CHANGELOG.md +++ b/packages/tezos/CHANGELOG.md @@ -1,5 +1,12 @@ # @wallet01/tezos +## 0.3.0-beta.1 + +### Patch Changes + +- Updated dependencies + - @wallet01/core@1.0.0-beta.1 + ## 0.3.0-beta.0 ### Minor Changes diff --git a/packages/tezos/package.json b/packages/tezos/package.json index 03c1c30..2af03ce 100644 --- a/packages/tezos/package.json +++ b/packages/tezos/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/tezos", - "version": "0.3.0-beta.0", + "version": "0.3.0-beta.1", "description": "", "main": "dist/index.js", "types": "dist/index.d.ts", From 3d8ada646235d2568bee8f80441b9438985d1826 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Tue, 17 Oct 2023 15:32:25 +0530 Subject: [PATCH 15/17] add: useeffects to establish event listeners --- .changeset/pre.json | 4 +++- .changeset/shy-turtles-flash.md | 5 +++++ examples/vite-react/CHANGELOG.md | 8 ++++++++ examples/vite-react/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/react/src/context.tsx | 3 +-- packages/react/src/hooks/index.ts | 4 ++-- packages/react/src/hooks/useAccount.ts | 4 ++-- packages/react/src/hooks/useChain.ts | 2 +- packages/react/src/hooks/useConnect.ts | 10 +++++++--- packages/react/src/hooks/useDisconnect.ts | 13 ++++++++----- packages/react/src/hooks/useMessage.ts | 13 ++++++++----- packages/react/src/hooks/useSwitch.ts | 13 ++++++++----- packages/react/src/utils/errors.ts | 4 ++-- 15 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 .changeset/shy-turtles-flash.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 9c160c4..3e85b9b 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -15,6 +15,8 @@ }, "changesets": [ "friendly-bobcats-repeat", - "happy-schools-add" + "happy-gifts-tap", + "happy-schools-add", + "shy-turtles-flash" ] } diff --git a/.changeset/shy-turtles-flash.md b/.changeset/shy-turtles-flash.md new file mode 100644 index 0000000..069d3c4 --- /dev/null +++ b/.changeset/shy-turtles-flash.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +updating client error with hook name diff --git a/examples/vite-react/CHANGELOG.md b/examples/vite-react/CHANGELOG.md index 992806b..31e8648 100644 --- a/examples/vite-react/CHANGELOG.md +++ b/examples/vite-react/CHANGELOG.md @@ -1,5 +1,13 @@ # vite-react +## 0.0.42-beta.2 + +### Patch Changes + +- Updated dependencies [82d8693] +- Updated dependencies + - @wallet01/react@1.0.0-beta.3 + ## 0.0.42-beta.1 ### Patch Changes diff --git a/examples/vite-react/package.json b/examples/vite-react/package.json index d42aa48..f8b7b37 100644 --- a/examples/vite-react/package.json +++ b/examples/vite-react/package.json @@ -1,7 +1,7 @@ { "name": "exmaple-vite-react", "private": true, - "version": "0.0.42-beta.1", + "version": "0.0.42-beta.2", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d8c94d0..99f6ceb 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @wallet01/react +## 1.0.0-beta.3 + +### Patch Changes + +- 82d8693: build then publish +- updating client error with hook name + ## 1.0.0-beta.1 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 8060326..633d9c2 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/react", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/react/src/context.tsx b/packages/react/src/context.tsx index 224411c..57047d2 100644 --- a/packages/react/src/context.tsx +++ b/packages/react/src/context.tsx @@ -1,4 +1,3 @@ -"use client"; import React, { FunctionComponent, useEffect, useState } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { BaseConnector, Client } from "@wallet01/core"; @@ -19,7 +18,7 @@ const Wallet01: FunctionComponent = ({ connectors, }) => { // if (typeof window === 'undefined') <>{children}; - const [queryClient] = React.useState(() => new QueryClient()); + const [queryClient] = useState(() => new QueryClient()); const [wallet01Client, setWalletClient] = useState(null); useEffect(() => { diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 011be57..36f52eb 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -5,7 +5,7 @@ import { useClient } from "./useClient"; import { useWallet } from "./useWallet"; import { useDisconnect } from "./useDisconnect"; import { useChain } from "./useChain"; -import { userAccount } from "./useAccount"; +import { useAccount } from "./useAccount"; export { useConnect, @@ -15,5 +15,5 @@ export { useWallet, useDisconnect, useChain, - userAccount, + useAccount, }; diff --git a/packages/react/src/hooks/useAccount.ts b/packages/react/src/hooks/useAccount.ts index 370dd94..5e4ee83 100644 --- a/packages/react/src/hooks/useAccount.ts +++ b/packages/react/src/hooks/useAccount.ts @@ -10,12 +10,12 @@ type useAccountConfig = { ) => Promise | void; }; -export const userAccount = (params?: useAccountConfig) => { +export const useAccount = (params?: useAccountConfig) => { const client = useContext(ClientProvider); const { address, addresses, activeConnector } = useStore(); useEffect(() => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useAccount"); if (params?.onAccountChange) client.emitter.on("accountsChanged", params.onAccountChange); diff --git a/packages/react/src/hooks/useChain.ts b/packages/react/src/hooks/useChain.ts index cedc564..7bdec82 100644 --- a/packages/react/src/hooks/useChain.ts +++ b/packages/react/src/hooks/useChain.ts @@ -12,7 +12,7 @@ export const useChain = (params?: useChainConfig) => { const { activeConnector, chainId } = useStore(); useEffect(() => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useChain"); if (params?.onChainChanged) client.emitter.on("chainChanged", params.onChainChanged); diff --git a/packages/react/src/hooks/useConnect.ts b/packages/react/src/hooks/useConnect.ts index 52ccd6e..03771e9 100644 --- a/packages/react/src/hooks/useConnect.ts +++ b/packages/react/src/hooks/useConnect.ts @@ -1,6 +1,6 @@ import { BaseConnector } from "@wallet01/core"; import { useMutation, UseMutationOptions } from "@tanstack/react-query"; -import { useCallback, useContext } from "react"; +import { useCallback, useContext, useEffect } from "react"; import { ClientProvider } from "../context"; import { ClientNotFoundError, ConnectorNotFoundError } from "../utils/errors"; import { ConnectionResponse } from "@wallet01/core/dist/types/methodTypes"; @@ -32,7 +32,7 @@ export const useConnect = (params?: UseConenctConfig) => { unknown >({ mutationFn: async ({ connector, chainId }: ConnectArgs) => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useConnect"); const connectors = client.store.getConnectors(); @@ -41,7 +41,6 @@ export const useConnect = (params?: UseConenctConfig) => { let connectionResult: ConnectionResponse; - if (params?.onConnect) client.emitter.on("connected", params.onConnect); if (chainId) { connectionResult = await connector.connect({ chainId: chainId }); } else { @@ -67,6 +66,11 @@ export const useConnect = (params?: UseConenctConfig) => { [client] ); + useEffect(() => { + if (!client) throw new ClientNotFoundError("useConnect"); + if (params?.onConnect) client.emitter.on("connected", params.onConnect); + }, [client]); + return { connect, connectAsync, diff --git a/packages/react/src/hooks/useDisconnect.ts b/packages/react/src/hooks/useDisconnect.ts index 306ac97..f502b00 100644 --- a/packages/react/src/hooks/useDisconnect.ts +++ b/packages/react/src/hooks/useDisconnect.ts @@ -1,7 +1,7 @@ import { UseMutationOptions, useMutation } from "@tanstack/react-query"; import { DisconnectionResponse } from "@wallet01/core/dist/types/methodTypes"; import { ClientProvider } from "../context"; -import { useCallback, useContext } from "react"; +import { useCallback, useContext, useEffect } from "react"; import { ClientNotFoundError, NoWalletConnectedError } from "../utils/errors"; import { TEcosystem } from "@wallet01/core/dist/store/storeTypes"; @@ -20,7 +20,7 @@ export const useDisconnect = (params?: useDisconnectConfig) => { unknown >({ mutationFn: async () => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useDisconnect"); const activeConnector = client.store.getActiveConnector(); @@ -28,9 +28,6 @@ export const useDisconnect = (params?: useDisconnectConfig) => { throw new NoWalletConnectedError({ methodName: "disconnect" }); const response = await activeConnector.disconnect(); - if (params?.onDisconnect) - client.emitter.on("disconnected", params.onDisconnect); - return response; }, onError: params?.onError, @@ -44,6 +41,12 @@ export const useDisconnect = (params?: useDisconnectConfig) => { return mutateAsync(); }, [client]); + useEffect(() => { + if (!client) throw new ClientNotFoundError("useDisconnect"); + if (params?.onDisconnect) + client.emitter.on("disconnected", params.onDisconnect); + }, [client]); + return { disconnect, disconnectAsync, diff --git a/packages/react/src/hooks/useMessage.ts b/packages/react/src/hooks/useMessage.ts index 685386e..d993301 100644 --- a/packages/react/src/hooks/useMessage.ts +++ b/packages/react/src/hooks/useMessage.ts @@ -1,5 +1,5 @@ import { UseMutationOptions, useMutation } from "@tanstack/react-query"; -import { useCallback, useContext } from "react"; +import { useCallback, useContext, useEffect } from "react"; import { ClientProvider } from "../context"; import { ClientNotFoundError, NoWalletConnectedError } from "../utils/errors"; import { @@ -40,16 +40,13 @@ export const useMessage = (params?: useMessageConfig) => { unknown >({ mutationFn: async ({ message }: SignMessageArgs) => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useMessage"); const activeConnector = client.store.getActiveConnector(); if (!activeConnector) throw new NoWalletConnectedError({ methodName: "signMessage" }); - if (params?.onMessageSigned) - client.emitter.on("messageSigned", params.onMessageSigned); - const response = await activeConnector.signMessage(message); return response; @@ -71,6 +68,12 @@ export const useMessage = (params?: useMessageConfig) => { [client] ); + useEffect(() => { + if (!client) throw new ClientNotFoundError("useMessage"); + if (params?.onMessageSigned) + client.emitter.on("messageSigned", params.onMessageSigned); + }, [client]); + return { hash: data?.signature, isLoading, diff --git a/packages/react/src/hooks/useSwitch.ts b/packages/react/src/hooks/useSwitch.ts index 7d245ff..f717e1b 100644 --- a/packages/react/src/hooks/useSwitch.ts +++ b/packages/react/src/hooks/useSwitch.ts @@ -1,6 +1,6 @@ import { UseMutationOptions, useMutation } from "@tanstack/react-query"; import { ChainSwitchResponse } from "@wallet01/core/dist/types/methodTypes"; -import { useCallback, useContext } from "react"; +import { useCallback, useContext, useEffect } from "react"; import { ClientProvider } from "../context"; import { ClientNotFoundError, @@ -40,7 +40,7 @@ export const useSwitch = (params?: useMessageConfig) => { unknown >({ mutationFn: async ({ chainId }: ChainSwitchArgs) => { - if (!client) throw new ClientNotFoundError(); + if (!client) throw new ClientNotFoundError("useSwitch"); const activeConnector = client.store.getActiveConnector(); const connectors = client.store.getConnectors(); @@ -58,9 +58,6 @@ export const useSwitch = (params?: useMessageConfig) => { walletName: activeConnector.name, }); - if (params?.onChainSwitched) - client.emitter.on("switchingChain", params.onChainSwitched); - const response = await activeConnector.switchChain(chainId); return response; @@ -82,6 +79,12 @@ export const useSwitch = (params?: useMessageConfig) => { [client] ); + useEffect(() => { + if (!client) throw new ClientNotFoundError("useSwitch"); + if (params?.onChainSwitched) + client.emitter.on("switchingChain", params.onChainSwitched); + }, [client]); + return { isLoading, isError, diff --git a/packages/react/src/utils/errors.ts b/packages/react/src/utils/errors.ts index 3ddefd7..a043490 100644 --- a/packages/react/src/utils/errors.ts +++ b/packages/react/src/utils/errors.ts @@ -1,8 +1,8 @@ export class ClientNotFoundError extends Error { name = "ClientNotFoundError"; - constructor() { + constructor(hookName: string) { super( - "Wallet01Client has not been initialised. Please initialise the client to use the hooks." + `Wallet01Client has not been initialised. Please initialise the client to use the ${hookName} hooks.` ); } } From a780d3bff7b55b48063a929ee64764f9fb038148 Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Tue, 17 Oct 2023 17:55:15 +0530 Subject: [PATCH 16/17] fix: final working enabled --- .changeset/gold-icons-tap.md | 5 ++++ .changeset/long-yaks-rescue.md | 5 ++++ .changeset/pink-lions-cry.md | 5 ++++ .changeset/pre.json | 7 +++++- .changeset/six-bees-whisper.md | 5 ++++ .changeset/smart-cups-judge.md | 5 ++++ examples/vite-react/CHANGELOG.md | 29 +++++++++++++++++++++++ examples/vite-react/package.json | 2 +- packages/react/CHANGELOG.md | 25 +++++++++++++++++++ packages/react/package.json | 2 +- packages/react/src/hooks/useAccount.ts | 10 ++++---- packages/react/src/hooks/useChain.ts | 10 ++++---- packages/react/src/hooks/useConnect.ts | 15 ++++++++++-- packages/react/src/hooks/useDisconnect.ts | 14 +++++++++-- packages/react/src/hooks/useMessage.ts | 14 +++++++++-- packages/react/src/hooks/useSwitch.ts | 14 +++++++++-- 16 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 .changeset/gold-icons-tap.md create mode 100644 .changeset/long-yaks-rescue.md create mode 100644 .changeset/pink-lions-cry.md create mode 100644 .changeset/six-bees-whisper.md create mode 100644 .changeset/smart-cups-judge.md diff --git a/.changeset/gold-icons-tap.md b/.changeset/gold-icons-tap.md new file mode 100644 index 0000000..409843e --- /dev/null +++ b/.changeset/gold-icons-tap.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +add onsuccessful connect option diff --git a/.changeset/long-yaks-rescue.md b/.changeset/long-yaks-rescue.md new file mode 100644 index 0000000..6d10657 --- /dev/null +++ b/.changeset/long-yaks-rescue.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +removing listeners in useEffect diff --git a/.changeset/pink-lions-cry.md b/.changeset/pink-lions-cry.md new file mode 100644 index 0000000..096c26d --- /dev/null +++ b/.changeset/pink-lions-cry.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +Adding alternative way of handling event listeners diff --git a/.changeset/pre.json b/.changeset/pre.json index 3e85b9b..1acadbb 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -15,8 +15,13 @@ }, "changesets": [ "friendly-bobcats-repeat", + "gold-icons-tap", "happy-gifts-tap", "happy-schools-add", - "shy-turtles-flash" + "long-yaks-rescue", + "pink-lions-cry", + "shy-turtles-flash", + "six-bees-whisper", + "smart-cups-judge" ] } diff --git a/.changeset/six-bees-whisper.md b/.changeset/six-bees-whisper.md new file mode 100644 index 0000000..bf8cd02 --- /dev/null +++ b/.changeset/six-bees-whisper.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +adding succes handlers to all the hooks diff --git a/.changeset/smart-cups-judge.md b/.changeset/smart-cups-judge.md new file mode 100644 index 0000000..3ad0f96 --- /dev/null +++ b/.changeset/smart-cups-judge.md @@ -0,0 +1,5 @@ +--- +"@wallet01/react": patch +--- + +removing unnecesary errors diff --git a/examples/vite-react/CHANGELOG.md b/examples/vite-react/CHANGELOG.md index 31e8648..25690d1 100644 --- a/examples/vite-react/CHANGELOG.md +++ b/examples/vite-react/CHANGELOG.md @@ -1,5 +1,34 @@ # vite-react +## 0.0.42-beta.6 + +### Patch Changes + +- Updated dependencies + - @wallet01/react@1.0.0-beta.8 + +## 0.0.42-beta.5 + +### Patch Changes + +- Updated dependencies + - @wallet01/react@1.0.0-beta.7 + +## 0.0.42-beta.4 + +### Patch Changes + +- Updated dependencies + - @wallet01/react@1.0.0-beta.6 + +## 0.0.42-beta.3 + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @wallet01/react@1.0.0-beta.5 + ## 0.0.42-beta.2 ### Patch Changes diff --git a/examples/vite-react/package.json b/examples/vite-react/package.json index f8b7b37..4f8eeb9 100644 --- a/examples/vite-react/package.json +++ b/examples/vite-react/package.json @@ -1,7 +1,7 @@ { "name": "exmaple-vite-react", "private": true, - "version": "0.0.42-beta.2", + "version": "0.0.42-beta.6", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 99f6ceb..59a953a 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,30 @@ # @wallet01/react +## 1.0.0-beta.8 + +### Patch Changes + +- adding succes handlers to all the hooks + +## 1.0.0-beta.7 + +### Patch Changes + +- add onsuccessful connect option + +## 1.0.0-beta.6 + +### Patch Changes + +- removing listeners in useEffect + +## 1.0.0-beta.5 + +### Patch Changes + +- Adding alternative way of handling event listeners +- removing unnecesary errors + ## 1.0.0-beta.3 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 633d9c2..1bff684 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/react", - "version": "1.0.0-beta.3", + "version": "1.0.0-beta.8", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", diff --git a/packages/react/src/hooks/useAccount.ts b/packages/react/src/hooks/useAccount.ts index 5e4ee83..a0d3e47 100644 --- a/packages/react/src/hooks/useAccount.ts +++ b/packages/react/src/hooks/useAccount.ts @@ -1,7 +1,6 @@ import { BaseConnector, useStore } from "@wallet01/core"; import { ClientProvider } from "../context"; import { useContext, useEffect } from "react"; -import { ClientNotFoundError } from "../utils/errors"; type useAccountConfig = { onAccountChange?: ( @@ -15,10 +14,13 @@ export const useAccount = (params?: useAccountConfig) => { const { address, addresses, activeConnector } = useStore(); useEffect(() => { - if (!client) throw new ClientNotFoundError("useAccount"); - - if (params?.onAccountChange) + if (params?.onAccountChange && client) client.emitter.on("accountsChanged", params.onAccountChange); + + return () => { + if (params?.onAccountChange && client) + client.emitter.off("accountsChanged", params.onAccountChange); + }; }, [activeConnector, client]); return { diff --git a/packages/react/src/hooks/useChain.ts b/packages/react/src/hooks/useChain.ts index 7bdec82..8454459 100644 --- a/packages/react/src/hooks/useChain.ts +++ b/packages/react/src/hooks/useChain.ts @@ -1,7 +1,6 @@ import { BaseConnector, useStore } from "@wallet01/core"; import { useContext, useEffect } from "react"; import { ClientProvider } from "../context"; -import { ClientNotFoundError } from "../utils/errors"; interface useChainConfig { onChainChanged?: (chainId: string, activeConnector: BaseConnector) => void; @@ -12,10 +11,13 @@ export const useChain = (params?: useChainConfig) => { const { activeConnector, chainId } = useStore(); useEffect(() => { - if (!client) throw new ClientNotFoundError("useChain"); - - if (params?.onChainChanged) + if (params?.onChainChanged && client) client.emitter.on("chainChanged", params.onChainChanged); + + return () => { + if (params?.onChainChanged && client) + client.emitter.off("chainChanged", params.onChainChanged); + }; }, [activeConnector, client]); return { diff --git a/packages/react/src/hooks/useConnect.ts b/packages/react/src/hooks/useConnect.ts index 03771e9..27313cf 100644 --- a/packages/react/src/hooks/useConnect.ts +++ b/packages/react/src/hooks/useConnect.ts @@ -13,6 +13,11 @@ type ConnectArgs = { type UseConenctConfig = { onError?: UseMutationOptions["onError"]; + onSuccessfulConnect?: UseMutationOptions< + ConnectionResponse, + Error, + ConnectArgs + >["onSuccess"]; onConnect?: ( address: string, chainId: string, @@ -49,6 +54,7 @@ export const useConnect = (params?: UseConenctConfig) => { return connectionResult; }, + onSuccess: params?.onSuccessfulConnect, onError: params?.onError, }); @@ -67,8 +73,13 @@ export const useConnect = (params?: UseConenctConfig) => { ); useEffect(() => { - if (!client) throw new ClientNotFoundError("useConnect"); - if (params?.onConnect) client.emitter.on("connected", params.onConnect); + if (params?.onConnect && client) + client.emitter.on("connected", params.onConnect); + + return () => { + if (params?.onConnect && client) + client.emitter.off("connected", params.onConnect); + }; }, [client]); return { diff --git a/packages/react/src/hooks/useDisconnect.ts b/packages/react/src/hooks/useDisconnect.ts index f502b00..996fc51 100644 --- a/packages/react/src/hooks/useDisconnect.ts +++ b/packages/react/src/hooks/useDisconnect.ts @@ -7,6 +7,11 @@ import { TEcosystem } from "@wallet01/core/dist/store/storeTypes"; interface useDisconnectConfig { onError?: UseMutationOptions["onError"]; + onSuccessfulDisconnect?: UseMutationOptions< + DisconnectionResponse, + Error, + void + >["onSuccess"]; onDisconnect?: (walletName: string, ecosystem: TEcosystem) => void; } @@ -30,6 +35,7 @@ export const useDisconnect = (params?: useDisconnectConfig) => { return response; }, + onSuccess: params?.onSuccessfulDisconnect, onError: params?.onError, }); @@ -42,9 +48,13 @@ export const useDisconnect = (params?: useDisconnectConfig) => { }, [client]); useEffect(() => { - if (!client) throw new ClientNotFoundError("useDisconnect"); - if (params?.onDisconnect) + if (params?.onDisconnect && client) client.emitter.on("disconnected", params.onDisconnect); + + return () => { + if (params?.onDisconnect && client) + client.emitter.off("disconnected", params.onDisconnect); + }; }, [client]); return { diff --git a/packages/react/src/hooks/useMessage.ts b/packages/react/src/hooks/useMessage.ts index d993301..1b92632 100644 --- a/packages/react/src/hooks/useMessage.ts +++ b/packages/react/src/hooks/useMessage.ts @@ -17,6 +17,11 @@ interface useMessageConfig { Error, SignMessageArgs >["onError"]; + onSuccessfulMessageSigned?: UseMutationOptions< + MessageSignedResponse, + Error, + SignMessageArgs + >["onSuccess"]; onMessageSigned?: ( signature: SignatureHash, activeConnector: BaseConnector @@ -51,6 +56,7 @@ export const useMessage = (params?: useMessageConfig) => { return response; }, + onSuccess: params?.onSuccessfulMessageSigned, onError: params?.onError, }); @@ -69,9 +75,13 @@ export const useMessage = (params?: useMessageConfig) => { ); useEffect(() => { - if (!client) throw new ClientNotFoundError("useMessage"); - if (params?.onMessageSigned) + if (params?.onMessageSigned && client) client.emitter.on("messageSigned", params.onMessageSigned); + + return () => { + if (params?.onMessageSigned && client) + client.emitter.off("messageSigned", params.onMessageSigned); + }; }, [client]); return { diff --git a/packages/react/src/hooks/useSwitch.ts b/packages/react/src/hooks/useSwitch.ts index f717e1b..e1b3b26 100644 --- a/packages/react/src/hooks/useSwitch.ts +++ b/packages/react/src/hooks/useSwitch.ts @@ -15,6 +15,11 @@ interface ChainSwitchArgs { interface useMessageConfig { onError?: UseMutationOptions["onError"]; + onSuccessfulChainSwitched?: UseMutationOptions< + ChainSwitchResponse, + Error, + ChainSwitchArgs + >["onSuccess"]; onChainSwitched?: ( fromChainId: string | "mainnet", toChainId: string | "mainnet", @@ -62,6 +67,7 @@ export const useSwitch = (params?: useMessageConfig) => { return response; }, + onSuccess: params?.onSuccessfulChainSwitched, onError: params?.onError, }); @@ -80,9 +86,13 @@ export const useSwitch = (params?: useMessageConfig) => { ); useEffect(() => { - if (!client) throw new ClientNotFoundError("useSwitch"); - if (params?.onChainSwitched) + if (params?.onChainSwitched && client) client.emitter.on("switchingChain", params.onChainSwitched); + + return () => { + if (params?.onChainSwitched && client) + client.emitter.off("switchingChain", params.onChainSwitched); + }; }, [client]); return { From ca6d735df3c3f19b561c6f2ed9fa450fab5f6b6b Mon Sep 17 00:00:00 2001 From: vatsal <0505m2003@gmail.com> Date: Thu, 19 Oct 2023 10:34:37 +0530 Subject: [PATCH 17/17] add: metamask connector targeting only metamask provider --- .changeset/pre.json | 1 + .changeset/real-seals-stare.md | 5 + examples/vite-react/CHANGELOG.md | 7 + examples/vite-react/package.json | 2 +- packages/evm/CHANGELOG.md | 6 + packages/evm/package.json | 5 +- packages/evm/src/connectors/metamask.ts | 299 ++++++++++++++++++++++++ packages/evm/src/index.ts | 20 +- pnpm-lock.yaml | 85 +------ 9 files changed, 336 insertions(+), 94 deletions(-) create mode 100644 .changeset/real-seals-stare.md create mode 100644 packages/evm/src/connectors/metamask.ts diff --git a/.changeset/pre.json b/.changeset/pre.json index 1acadbb..96a0cee 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -20,6 +20,7 @@ "happy-schools-add", "long-yaks-rescue", "pink-lions-cry", + "real-seals-stare", "shy-turtles-flash", "six-bees-whisper", "smart-cups-judge" diff --git a/.changeset/real-seals-stare.md b/.changeset/real-seals-stare.md new file mode 100644 index 0000000..d34c041 --- /dev/null +++ b/.changeset/real-seals-stare.md @@ -0,0 +1,5 @@ +--- +"@wallet01/evm": patch +--- + +Adding metamask connector diff --git a/examples/vite-react/CHANGELOG.md b/examples/vite-react/CHANGELOG.md index 25690d1..105c089 100644 --- a/examples/vite-react/CHANGELOG.md +++ b/examples/vite-react/CHANGELOG.md @@ -1,5 +1,12 @@ # vite-react +## 0.0.42-beta.7 + +### Patch Changes + +- Updated dependencies + - @wallet01/evm@0.12.0-beta.2 + ## 0.0.42-beta.6 ### Patch Changes diff --git a/examples/vite-react/package.json b/examples/vite-react/package.json index 4f8eeb9..7e0b49c 100644 --- a/examples/vite-react/package.json +++ b/examples/vite-react/package.json @@ -1,7 +1,7 @@ { "name": "exmaple-vite-react", "private": true, - "version": "0.0.42-beta.6", + "version": "0.0.42-beta.7", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/evm/CHANGELOG.md b/packages/evm/CHANGELOG.md index 1a3bed4..29a9749 100644 --- a/packages/evm/CHANGELOG.md +++ b/packages/evm/CHANGELOG.md @@ -1,5 +1,11 @@ # @wallet01/evm +## 0.12.0-beta.2 + +### Patch Changes + +- Adding metamask connector + ## 0.12.0-beta.1 ### Patch Changes diff --git a/packages/evm/package.json b/packages/evm/package.json index e1e275d..a66110f 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -1,6 +1,6 @@ { "name": "@wallet01/evm", - "version": "0.12.0-beta.1", + "version": "0.12.0-beta.2", "main": "dist/index.cjs", "types": "dist/index.d.ts", "import": "dist/index.js", @@ -21,8 +21,7 @@ "@walletconnect/modal": "^2.5.2", "@web3modal/core": "^2.2.2", "ethers": "^5.7.2", - "eventemitter3": "^4.0.7", - "viem": "^1.16.4" + "eventemitter3": "^4.0.7" }, "devDependencies": { "rimraf": "^3.0.2", diff --git a/packages/evm/src/connectors/metamask.ts b/packages/evm/src/connectors/metamask.ts new file mode 100644 index 0000000..7495d1d --- /dev/null +++ b/packages/evm/src/connectors/metamask.ts @@ -0,0 +1,299 @@ +import { + BaseConnector, + ProviderNotFoundError, + UnknownError, + UnrecognisedChainError, + UserRejectedRequestError, +} from "@wallet01/core"; +import { Web3Provider } from "@ethersproject/providers"; +import { + AddChainParameter, + ChainSwitchResponse, +} from "@wallet01/core/dist/types/methodTypes"; +import { hexValue, hexlify, toUtf8Bytes } from "ethers/lib/utils.js"; +import { ProviderRpcError } from "@walletconnect/ethereum-provider/dist/types/types"; + +export class MetamaskConnector extends BaseConnector { + static #instance: BaseConnector; + provider!: Web3Provider; + + protected constructor() { + super("metamask", "ethereum"); + } + + static init() { + if (!MetamaskConnector.#instance) { + MetamaskConnector.#instance = + new MetamaskConnector() as BaseConnector; + } + return MetamaskConnector.#instance; + } + + async getProvider() { + try { + if (this.provider) return this.provider; + + const windowProvider = this.getReady(window.ethereum); + + if (!windowProvider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const provider = new Web3Provider(windowProvider); + + this.provider = provider; + return this.provider; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getProvider", + }); + } + } + + async getAccount(): Promise { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const accounts = (await this.provider.send( + "eth_requestAccounts", + [] + )) as string[]; + + return accounts; + } catch (err) { + console.error(err); + throw new UnknownError({ + walletName: this.name, + atFunction: "getAccount", + }); + } + } + + async getChainId(): Promise { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const id = (await this.provider.send("eth_chainId", [])) as string; + + const chainId = parseInt(id, 16).toString(); + return chainId; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "getChainId", + }); + } + } + + async switchChain( + chainId: string, + options?: AddChainParameter | undefined + ): Promise { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const oldChainId = await this.getChainId(); + const hexChainId = hexValue(Number(chainId)); + const params = [{ chainId: hexChainId }]; + + try { + await this.provider.send("wallet_switchEthereumChain", params); + } catch (error) { + if ( + (error as ProviderRpcError).code && + (error as ProviderRpcError).code === 4902 + ) { + if (!options) { + throw new UnrecognisedChainError({ + walletName: this.name, + chainId, + }); + } + + await this.provider.send("wallet_addEthereumChain", [options]); + } + } + + this.emitter.emit( + "switchingChain", + oldChainId, + chainId, + MetamaskConnector.#instance + ); + + return { + fromChainId: oldChainId, + toChainId: chainId, + activeConnector: MetamaskConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "switchChain", + }); + } + } + + async connect(options?: { chainId: string }) { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + const response = await this.provider.send("eth_requestAccounts", []); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + window.ethereum.on("accountsChanged", this._onAccountsChanged); + window.ethereum.on("disconnect", this._onDisconnect); + window.ethereum.on("chainChanged", this._onChainChanged); + + const currentId = await this.getChainId(); + if (options?.chainId && currentId !== options.chainId) { + await this.switchChain(options.chainId); + } + + const address = await this.getAccount(); + + this.emitter.emit( + "connected", + address[0]!, + currentId, + this.name, + this.ecosystem, + MetamaskConnector.#instance + ); + + return { + address: address[0]!, + walletName: this.name, + chainId: currentId, + ecosystem: this.ecosystem, + activeConnector: MetamaskConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "connect", + }); + } + } + + async disconnect() { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + + window.ethereum.removeListener( + "accountsChanged", + this._onAccountsChanged + ); + window.ethereum.removeListener("chainChanged", this._onChainChanged); + window.ethereum.removeListener("disconnect", this._onDisconnect); + + this.emitter.emit("disconnected", this.name, this.ecosystem); + return { + walletName: this.name, + ecosystem: this.ecosystem, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "disconnect", + }); + } + } + + async signMessage(message: string) { + if (!this.provider) await this.getProvider(); + try { + if (!this.provider) + throw new ProviderNotFoundError({ walletName: this.name }); + const address = await this.getAccount(); + + const hexMessage = hexlify(toUtf8Bytes(message)); + + const response = await this.provider.send("personal_sign", [ + hexMessage, + address[0], + ]); + + if ((response as any).code === 4001) { + throw new UserRejectedRequestError(); + } + + this.emitter.emit( + "messageSigned", + response as string, + MetamaskConnector.#instance + ); + + return { + signature: response as string, + activeConnector: MetamaskConnector.#instance, + }; + } catch (error) { + console.error(error); + throw new UnknownError({ + walletName: this.name, + atFunction: "signMessage", + }); + } + } + + protected _onAccountsChanged = (accounts: string[]) => { + this.emitter.emit("accountsChanged", accounts, MetamaskConnector.#instance); + }; + + protected _onChainChanged = (hexChainId: string) => { + const chainId = parseInt(hexChainId, 16).toString(); + this.emitter.emit("chainChanged", chainId, MetamaskConnector.#instance); + }; + + protected _onDisconnect = (error: any) => { + console.error({ + error, + }); + this.emitter.emit("disconnected", this.name, this.ecosystem); + }; + + private getReady(ethereum?: any) { + const isMetaMask = !!ethereum?.isMetaMask; + if (!isMetaMask) return; + // Brave tries to make itself look like MetaMask + // Could also try RPC `web3_clientVersion` if following is unreliable + if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) return; + if (ethereum.isApexWallet) return; + if (ethereum.isAvalanche) return; + if (ethereum.isBitKeep) return; + if (ethereum.isBlockWallet) return; + if (ethereum.isCoin98) return; + if (ethereum.isFordefi) return; + if (ethereum.isMathWallet) return; + if (ethereum.isOkxWallet || ethereum.isOKExWallet) return; + if (ethereum.isOneInchIOSWallet || ethereum.isOneInchAndroidWallet) return; + if (ethereum.isOpera) return; + if (ethereum.isPortal) return; + if (ethereum.isRabby) return; + if (ethereum.isDefiant) return; + if (ethereum.isTokenPocket) return; + if (ethereum.isTokenary) return; + if (ethereum.isZeal) return; + if (ethereum.isZerion) return; + return ethereum; + } +} diff --git a/packages/evm/src/index.ts b/packages/evm/src/index.ts index 0f2e2fb..6cff11c 100644 --- a/packages/evm/src/index.ts +++ b/packages/evm/src/index.ts @@ -1,7 +1,15 @@ -import { InjectedConnector } from './connectors/injected'; -import { CoinbaseConnector } from './connectors/coinbase'; -import { WalletconnectConnector } from './connectors/walletconnect'; -import { BananaConnector } from './connectors/banana'; -import { OkxWalletConnector } from './connectors/okxwallet'; +import { InjectedConnector } from "./connectors/injected"; +import { CoinbaseConnector } from "./connectors/coinbase"; +import { WalletconnectConnector } from "./connectors/walletconnect"; +import { BananaConnector } from "./connectors/banana"; +import { OkxWalletConnector } from "./connectors/okxwallet"; +import { MetamaskConnector } from "./connectors/metamask"; -export { InjectedConnector, CoinbaseConnector, WalletconnectConnector, BananaConnector, OkxWalletConnector }; +export { + InjectedConnector, + CoinbaseConnector, + WalletconnectConnector, + BananaConnector, + OkxWalletConnector, + MetamaskConnector, +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 178378d..c041e92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -240,9 +240,6 @@ importers: eventemitter3: specifier: ^4.0.7 version: 4.0.7 - viem: - specifier: ^1.16.4 - version: 1.16.4(typescript@4.9.4) devDependencies: rimraf: specifier: ^3.0.2 @@ -384,10 +381,6 @@ packages: - utf-8-validate dev: false - /@adraffy/ens-normalize@1.9.4: - resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} - dev: false - /@airgap/beacon-core@4.0.10: resolution: {integrity: sha512-iOAKZRD5BSDFfZKa++FoYBnfDhTLZSzKUbhF/AI6CnnTgzZaEbkTIs+/XVpFhcJQY58hJN77cGnioeG2/WCWkw==} dependencies: @@ -1735,25 +1728,6 @@ packages: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true - /@scure/base@1.1.3: - resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} - dev: false - - /@scure/bip32@1.3.2: - resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} - dependencies: - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@scure/base': 1.1.3 - dev: false - - /@scure/bip39@1.2.1: - resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} - dependencies: - '@noble/hashes': 1.3.2 - '@scure/base': 1.1.3 - dev: false - /@solana/buffer-layout@4.0.0: resolution: {integrity: sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==} engines: {node: '>=5.10'} @@ -2697,20 +2671,6 @@ packages: through: 2.3.8 dev: false - /abitype@0.9.8(typescript@4.9.4): - resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3 >=3.19.1 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - dependencies: - typescript: 4.9.4 - dev: false - /acorn-jsx@5.3.2(acorn@7.4.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5059,14 +5019,6 @@ packages: ws: 7.5.9 dev: false - /isows@1.0.3(ws@8.13.0): - resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} - peerDependencies: - ws: '*' - dependencies: - ws: 8.13.0 - dev: false - /jayson@3.7.0: resolution: {integrity: sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ==} engines: {node: '>=8'} @@ -7035,6 +6987,7 @@ packages: /typescript@4.9.4: resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} + dev: true /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} @@ -7152,29 +7105,6 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - /viem@1.16.4(typescript@4.9.4): - resolution: {integrity: sha512-T9ziN3EERXz0BtQSS2VJM+P1EJ2W7K7PviobFrmvWCEYmNQ/vJDhfFqGjvq0ZL9LVz9HvevCbenEy8oIdMEZ+w==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@adraffy/ens-normalize': 1.9.4 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@scure/bip32': 1.3.2 - '@scure/bip39': 1.2.1 - abitype: 0.9.8(typescript@4.9.4) - isows: 1.0.3(ws@8.13.0) - typescript: 4.9.4 - ws: 8.13.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - dev: false - /vite@3.2.4: resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7349,19 +7279,6 @@ packages: utf-8-validate: 5.0.10 dev: false - /ws@8.13.0: - resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'}