Skip to content

Commit

Permalink
feat: add CyberProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
akasuv committed Oct 23, 2023
1 parent f2c97aa commit 4382146
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 5 deletions.
8 changes: 4 additions & 4 deletions src/CyberApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ class CyberApp {
return (await this.connect()) as CyberAccount;
}

public connect() {
public async connect(): Promise<CyberAccount> {
this.messenger.sendMessage({
name: "connect",
});

return new Promise((resolve, reject) => {
return await new Promise((resolve, reject) => {
this.messenger.onMessage((message) => {
if (message.target === "CyberApp") {
if (message.event.name === "connect") {
if (message.event.data?.data?.result === "success") {
this.cyberWallet.setConnection(true);
this.cyberWallet.setCyberAccount(
this.cyberWallet?.setConnection(true);
this.cyberWallet?.setCyberAccount(
message.event.data?.data?.cyberAccount,
);
resolve(message.event.data?.data?.cyberAccount);
Expand Down
116 changes: 116 additions & 0 deletions src/CyberProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import CyberApp from "./CyberApp";
import type { EIP1193Provider } from "./types";
import { availableChains, type ChainName } from "./config/chains";
import { EventEmitter } from "events";
import {
ProviderDisconnectedError,
createPublicClient,
http,
type PublicClient,
} from "viem";
import Chain from "./Chain";

class CyberProvider extends EventEmitter implements EIP1193Provider {
public name: "CyberWallet";
public cyberApp: CyberApp;
public chainId: number;
public readonly isMetaMask: any;
public _events: {
connect?: () => void;
};
public chain?: Chain;
public publicClient: PublicClient;

constructor({ app, chainId }: { app: CyberApp; chainId: number }) {
super();
this.name = "CyberWallet";
this.cyberApp = app;
this.chainId = chainId;
this.isMetaMask = false;
this.chain = this.getChainByChainId(this.chainId);
this._events = {};
this.publicClient = this.setPublicClient(this.chainId);
}

setPublicClient(chainId: number): PublicClient {
return createPublicClient({
chain: Object.values(availableChains).find(
(chain) => chain.id === chainId,
)!,
transport: http(),
});
}

async connect(): Promise<void> {
this.emit("connect", { chainId: `0x${this.chainId.toString(16)}` });
return;
}

async disconnect(): Promise<void> {
this.emit("disconnect", new ProviderDisconnectedError(Error()));
return;
}

private getChainKeyByChainId(chainId: number) {
const chainObj = Object.entries(availableChains).find(
([_, chain]) => chain.id === chainId,
);

if (!chainObj) {
throw new Error(`ChainId ${chainId} is not supported.`);
}

return chainObj[0] as ChainName;
}

private getChainByChainId(id: number) {
const chainKey = this.getChainKeyByChainId(id);
return this.cyberApp.cyberWallet?.[chainKey];
}

async request(request: { method: string; params?: any[] }): Promise<any> {
const { method, params = [] } = request;

switch (method) {
case "wallet_switchEthereumChain": {
this.chainId = params[0].chainId;
this.chain = this.getChainByChainId(Number(this.chainId));
this.publicClient = this.setPublicClient(Number(this.chainId));
this.emit("chainChanged", this.chainId);
return;
}

case "eth_chainId":
return `0x${this.chainId.toString(16)}`;

case "eth_sendTransaction": {
const data = params[0].data || "0x";

return this.chain?.sendTransaction({ ...params[0], data });
}

case "eth_requestAccounts": {
if (!this.cyberApp.cyberWallet?.cyberAccount) {
await this.cyberApp.connect();
}

return [this.cyberApp.cyberWallet?.cyberAccount?.address];
}

case "eth_accounts": {
if (!this.cyberApp.cyberWallet?.cyberAccount) {
await this.cyberApp.connect();
}
return [this.cyberApp.cyberWallet?.cyberAccount?.address];
}

default:
return await this.publicClient.request({
method: method as any,
params: params as any,
});
}
}
}

export default CyberProvider;
4 changes: 3 additions & 1 deletion src/config/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ const chainNames = [
"scrollSepolia",
] as const;

export const availableChains: Record<(typeof chainNames)[number], Chain> = {
export type ChainName = (typeof chainNames)[number];

export const availableChains: Record<ChainName, Chain> = {
optimism,
optimismGoerli,
polygon,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as CyberApp } from "./CyberApp";
export { default as CyberWallet } from "./CyberWallet";
export { default as EventError } from "./EventError";
export { default as CyberProvider } from "./CyberProvider";
export * from "./types";
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Hex } from "viem";
import { EventEmitter } from "events";

export type WalletEventName = "connect" | "disconnect" | "action";

Expand Down Expand Up @@ -60,3 +61,12 @@ export type AppInfo = {
export enum ErrorType {
SendTransactionError = "SendTransactionError",
}

export interface EIP1193Provider extends EventEmitter {
request(args: { method: string; params?: unknown[] }): Promise<unknown>;
}

export interface EIP1193ProviderError extends Error {
code: number;
data?: unknown;
}

0 comments on commit 4382146

Please sign in to comment.