Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e2994bfff | ||
|
|
ecc5a5054a | ||
|
|
de7deef444 |
@@ -33,6 +33,7 @@ import { PartyActiveOrdersHandler } from './party-active-orders-handler';
|
||||
import { MaybeConnectEagerly } from './maybe-connect-eagerly';
|
||||
import { TransactionHandlers } from './transaction-handlers';
|
||||
import { useT } from '../lib/use-t';
|
||||
import { Test } from './test/test';
|
||||
|
||||
const Title = () => {
|
||||
const t = useT();
|
||||
@@ -135,4 +136,6 @@ function VegaTradingApp(props: AppProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default VegaTradingApp;
|
||||
export default function () {
|
||||
return <Test />;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
export type Chain = {
|
||||
id: string;
|
||||
testnet: boolean;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const fairground = {
|
||||
id: 'vega-fairground-202305051805',
|
||||
testnet: true,
|
||||
name: 'Fairground',
|
||||
};
|
||||
|
||||
export const stagnet = {
|
||||
id: 'vega-stagnet1-202307191148',
|
||||
testnet: true,
|
||||
name: 'Stagnet',
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
type Transaction,
|
||||
type TransactionResponse,
|
||||
} from '@vegaprotocol/wallet';
|
||||
|
||||
export enum JsonRpcMethod {
|
||||
ConnectWallet = 'client.connect_wallet',
|
||||
DisconnectWallet = 'client.disconnect_wallet',
|
||||
ListKeys = 'client.list_keys',
|
||||
SignTransaction = 'client.sign_transaction',
|
||||
SendTransaction = 'client.send_transaction',
|
||||
GetChainId = 'client.get_chain_id',
|
||||
}
|
||||
|
||||
export interface IWalletError {
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface TransactionParams {
|
||||
publicKey: string;
|
||||
transaction: Transaction;
|
||||
sendingMode: 'TYPE_SYNC';
|
||||
}
|
||||
|
||||
export interface Connector {
|
||||
id: string;
|
||||
|
||||
connectWallet(chainId: string): Promise<{ success: boolean } | IWalletError>;
|
||||
|
||||
disconnectWallet(): Promise<{ success: boolean } | IWalletError>;
|
||||
|
||||
getChainId(): Promise<{ chainId: string } | IWalletError>;
|
||||
|
||||
listKeys(): Promise<
|
||||
Array<{ publicKey: string; name: string }> | IWalletError
|
||||
>;
|
||||
|
||||
isConnected(): Promise<{ connected: boolean } | IWalletError>;
|
||||
|
||||
sendTransaction(
|
||||
params: TransactionParams
|
||||
): Promise<TransactionResponse | IWalletError>;
|
||||
|
||||
on(event: string, callback: () => void): void;
|
||||
|
||||
off(event: string, callback: () => void): void;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { TransactionParams, type Connector } from '.';
|
||||
|
||||
export class InjectedConnector implements Connector {
|
||||
id = 'injected';
|
||||
|
||||
async connectWallet(chainId: string) {
|
||||
try {
|
||||
await window.vega.connectWallet({ chainId });
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { error: 'failed to connect' };
|
||||
}
|
||||
}
|
||||
|
||||
async disconnectWallet() {
|
||||
try {
|
||||
await window.vega.disconnectWallet();
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { error: 'failed to disconnect' };
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated, pass chain on connect
|
||||
async getChainId() {
|
||||
try {
|
||||
const res = await window.vega.getChainId();
|
||||
return { chainId: res.chainID };
|
||||
} catch (err) {
|
||||
return { error: 'failed to get chain id' };
|
||||
}
|
||||
}
|
||||
|
||||
async listKeys() {
|
||||
try {
|
||||
const res = await window.vega.listKeys();
|
||||
return res.keys;
|
||||
} catch (err) {
|
||||
return { error: 'failed to list keys' };
|
||||
}
|
||||
}
|
||||
|
||||
async isConnected() {
|
||||
try {
|
||||
const res = await window.vega.isConnected();
|
||||
return { connected: res };
|
||||
} catch (err) {
|
||||
return { error: 'failed to check isConnected' };
|
||||
}
|
||||
}
|
||||
|
||||
async sendTransaction(params: TransactionParams) {
|
||||
try {
|
||||
const res = await window.vega.sendTransaction(params);
|
||||
|
||||
return {
|
||||
transactionHash: res.transactionHash,
|
||||
signature: res.transaction.signature.value,
|
||||
receivedAt: res.receivedAt,
|
||||
sentAt: res.sentAt,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return { error: 'failed to send transaction' };
|
||||
}
|
||||
}
|
||||
|
||||
on(event: 'client.disconnected', callback: () => void) {
|
||||
window.vega.on(event, callback);
|
||||
}
|
||||
|
||||
off(event: 'client.disconnected') {
|
||||
window.vega.off(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import { JsonRpcMethod, type Connector, type TransactionParams } from '.';
|
||||
|
||||
type JsonRpcConnectorConfig = { url: string };
|
||||
|
||||
export class JsonRpcConnector implements Connector {
|
||||
id = 'json-rpc';
|
||||
config: JsonRpcConnectorConfig;
|
||||
requestId: number = 0;
|
||||
token: string | null = null;
|
||||
|
||||
constructor(config: JsonRpcConnectorConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async connectWallet(desiredChainId: string) {
|
||||
try {
|
||||
const { chainId } = await this.getChainId();
|
||||
|
||||
if (chainId !== desiredChainId) {
|
||||
throw new Error('incorrect chain id');
|
||||
}
|
||||
|
||||
const { response } = await this.request(JsonRpcMethod.ConnectWallet, {
|
||||
hostname: window.location.hostname,
|
||||
});
|
||||
|
||||
const token = response.headers.get('Authorization');
|
||||
|
||||
if (response.ok && token) {
|
||||
this.token = token;
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
return { error: 'failed to connect' };
|
||||
} catch (err) {
|
||||
return { error: 'failed to connect' };
|
||||
}
|
||||
}
|
||||
|
||||
async disconnectWallet() {
|
||||
try {
|
||||
await this.request(JsonRpcMethod.DisconnectWallet);
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { error: 'failed to disconnect' };
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated, pass chain on connect
|
||||
async getChainId() {
|
||||
try {
|
||||
const { data } = await this.request(JsonRpcMethod.GetChainId);
|
||||
return { chainId: data.result.chainID };
|
||||
} catch (err) {
|
||||
return { error: 'failed to get chain id' };
|
||||
}
|
||||
}
|
||||
|
||||
async listKeys() {
|
||||
try {
|
||||
const { data } = await this.request(JsonRpcMethod.ListKeys);
|
||||
return data.result.keys as Array<{ publicKey: string; name: string }>;
|
||||
} catch (err) {
|
||||
return { error: 'failed to list keys' };
|
||||
}
|
||||
}
|
||||
|
||||
async isConnected() {
|
||||
try {
|
||||
await this.listKeys();
|
||||
return { connected: true };
|
||||
} catch (err) {
|
||||
return { error: 'failed to check isConnected' };
|
||||
}
|
||||
}
|
||||
|
||||
async sendTransaction(params: TransactionParams) {
|
||||
try {
|
||||
const { data } = await this.request(
|
||||
JsonRpcMethod.SendTransaction,
|
||||
params
|
||||
);
|
||||
|
||||
return {
|
||||
transactionHash: data.result.transactionHash,
|
||||
signature: data.result.transaction.signature.value,
|
||||
receivedAt: data.result.receivedAt,
|
||||
sentAt: data.result.sentAt,
|
||||
};
|
||||
} catch (err) {
|
||||
return { error: 'failed to send transaction' };
|
||||
}
|
||||
}
|
||||
|
||||
private async request(method: JsonRpcMethod, params?: any) {
|
||||
const headers = new Headers();
|
||||
|
||||
if (this.token) {
|
||||
headers.set('Authorization', this.token);
|
||||
}
|
||||
|
||||
const response = await fetch(this.config.url, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
id: `${this.requestId++}`,
|
||||
jsonrpc: '2.0',
|
||||
method,
|
||||
params,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
return {
|
||||
data,
|
||||
response,
|
||||
};
|
||||
}
|
||||
|
||||
on() {
|
||||
console.warn('events are not supported in json rpc wallet');
|
||||
}
|
||||
|
||||
off() {
|
||||
console.warn('events are not supported in json rpc wallet');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
import { JsonRpcMethod, type Connector, type TransactionParams } from '.';
|
||||
|
||||
enum EthereumMethod {
|
||||
RequestSnaps = 'wallet_requestSnaps',
|
||||
GetSnaps = 'wallet_getSnaps',
|
||||
InvokeSnap = 'wallet_invokeSnap',
|
||||
}
|
||||
|
||||
type SnapConfig = {
|
||||
id: string;
|
||||
node: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export class SnapConnector implements Connector {
|
||||
id = 'snap';
|
||||
|
||||
config: SnapConfig;
|
||||
|
||||
constructor(config: SnapConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async connectWallet(desiredChainId: string) {
|
||||
try {
|
||||
await this.requestSnap();
|
||||
|
||||
const { chainId } = await this.getChainId();
|
||||
|
||||
if (chainId !== desiredChainId) {
|
||||
throw new Error('incorrect chain id');
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { error: 'failed to connect' };
|
||||
}
|
||||
}
|
||||
|
||||
async disconnectWallet() {
|
||||
console.warn('disconnectWallet not implemented');
|
||||
return { error: 'failed to disconnect' };
|
||||
}
|
||||
|
||||
// deprecated, pass chain on connect
|
||||
async getChainId() {
|
||||
try {
|
||||
const res = await this.invokeSnap(JsonRpcMethod.GetChainId, {
|
||||
networkEndpoints: [this.config.node],
|
||||
});
|
||||
return { chainId: res.chainID };
|
||||
} catch (err) {
|
||||
return { error: 'failed to get chain id' };
|
||||
}
|
||||
}
|
||||
|
||||
async listKeys() {
|
||||
try {
|
||||
const res = await this.invokeSnap(JsonRpcMethod.ListKeys);
|
||||
return res.keys as Array<{ publicKey: string; name: string }>;
|
||||
} catch (err) {
|
||||
return { error: 'failed to list keys' };
|
||||
}
|
||||
}
|
||||
|
||||
async isConnected() {
|
||||
console.warn('isConnected not implemented');
|
||||
return { error: 'failed to check if connected' };
|
||||
}
|
||||
|
||||
async sendTransaction(params: TransactionParams) {
|
||||
try {
|
||||
const res = await this.invokeSnap(JsonRpcMethod.SendTransaction, {
|
||||
publicKey: params.publicKey,
|
||||
sendingMode: params.sendingMode,
|
||||
transaction: params.transaction,
|
||||
networkEndpoints: [this.config.node],
|
||||
});
|
||||
|
||||
return {
|
||||
transactionHash: res.transactionHash,
|
||||
signature: res.transaction.signature.value,
|
||||
receivedAt: res.receivedAt,
|
||||
sentAt: res.sentAt,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return { error: 'failed to send transaction' };
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Snap methods
|
||||
////////////////////////////////////
|
||||
|
||||
async requestSnap() {
|
||||
const res = await this.request(EthereumMethod.RequestSnaps, {
|
||||
[this.config.id]: {
|
||||
version: this.config.version,
|
||||
},
|
||||
});
|
||||
console.log(res);
|
||||
}
|
||||
|
||||
async getSnap() {
|
||||
const snaps = await this.request(EthereumMethod.GetSnaps);
|
||||
return Object.values(snaps).find(
|
||||
(s) => s.id === this.config.id && s.version === this.config.version
|
||||
);
|
||||
}
|
||||
|
||||
async invokeSnap(method: JsonRpcMethod, params?: any) {
|
||||
return await this.request(EthereumMethod.InvokeSnap, {
|
||||
snapId: this.config.id,
|
||||
request: {
|
||||
method: method,
|
||||
params,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async request(method: EthereumMethod, params?: any) {
|
||||
if (!window.ethereum) {
|
||||
throw new Error('no window.ethereum');
|
||||
}
|
||||
|
||||
// @ts-ignore ethereum types a bit mangled from web3-react
|
||||
return window.ethereum.request({
|
||||
method,
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
on() {
|
||||
console.warn('events are not supported in json rpc wallet');
|
||||
}
|
||||
|
||||
off() {
|
||||
console.warn('events are not supported in json rpc wallet');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
import { StoreApi, createStore } from 'zustand/vanilla';
|
||||
import { useStore } from 'zustand';
|
||||
|
||||
import { InjectedConnector } from './injected-connector';
|
||||
import { JsonRpcConnector } from './json-rpc-connector';
|
||||
import { SnapConnector } from './snap-connector';
|
||||
import { Chain, fairground, stagnet } from './chains';
|
||||
import { Connector, TransactionParams } from '.';
|
||||
import {
|
||||
PropsWithChildren,
|
||||
createContext,
|
||||
createElement,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Dialog } from '@vegaprotocol/ui-toolkit';
|
||||
import { TransactionResponse } from '@vegaprotocol/wallet';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
|
||||
const injected = new InjectedConnector();
|
||||
const jsonRpc = new JsonRpcConnector({
|
||||
url: 'http://localhost:1789/api/v2/requests',
|
||||
});
|
||||
const snap = new SnapConnector({
|
||||
node: 'https://api.n08.testnet.vega.rocks',
|
||||
id: 'npm:@vegaprotocol/snap',
|
||||
version: '0.3.1',
|
||||
});
|
||||
|
||||
type Key = {
|
||||
publicKey: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type Store = {
|
||||
chainId: string;
|
||||
status: 'disconnected' | 'connecting' | 'connected';
|
||||
current: string | undefined;
|
||||
keys: Key[];
|
||||
setKeys: (keys: Key[]) => void;
|
||||
};
|
||||
|
||||
type Config = { chains: Chain[]; connectors: Connector[] };
|
||||
|
||||
type Wallet = {
|
||||
store: StoreApi<Store>;
|
||||
connectors: Connector[];
|
||||
connect: (id: string) => Promise<void>;
|
||||
disconnect: () => Promise<void>;
|
||||
sendTransaction: (params: TransactionParams) => Promise<TransactionResponse>;
|
||||
};
|
||||
|
||||
function createConfig(cfg: Config): Wallet {
|
||||
const connectors = createStore(() => cfg.connectors);
|
||||
|
||||
const store = createStore<Store>((set) => ({
|
||||
chainId: cfg.chains[0].id,
|
||||
status: 'disconnected',
|
||||
current: undefined,
|
||||
keys: [],
|
||||
setKeys: (keys) => {
|
||||
set({ keys });
|
||||
},
|
||||
}));
|
||||
|
||||
async function connect(id: string) {
|
||||
if (store.getState().status === 'connecting') {
|
||||
return;
|
||||
}
|
||||
|
||||
const connector = connectors.getState().find((x) => x.id === id);
|
||||
|
||||
if (!connector) return;
|
||||
|
||||
try {
|
||||
store.setState({ status: 'connecting', current: id });
|
||||
|
||||
const connectWalletRes = await connector.connectWallet(
|
||||
store.getState().chainId
|
||||
);
|
||||
|
||||
if ('error' in connectWalletRes) {
|
||||
throw new Error('failed to connect');
|
||||
}
|
||||
|
||||
const listKeysRes = await connector.listKeys();
|
||||
|
||||
if ('error' in listKeysRes) {
|
||||
throw new Error('failed to get keys');
|
||||
}
|
||||
|
||||
store.setState({
|
||||
keys: listKeysRes,
|
||||
status: 'connected',
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
store.setState({ status: 'disconnected', current: undefined, keys: [] });
|
||||
}
|
||||
}
|
||||
|
||||
async function disconnect() {
|
||||
const connector = connectors
|
||||
.getState()
|
||||
.find((x) => x.id === store.getState().current);
|
||||
|
||||
if (!connector) return;
|
||||
|
||||
store.setState({ status: 'disconnected', current: undefined, keys: [] });
|
||||
}
|
||||
|
||||
async function sendTransaction(params: TransactionParams) {
|
||||
const connector = connectors
|
||||
.getState()
|
||||
.find((x) => x.id === store.getState().current);
|
||||
|
||||
if (!connector) return;
|
||||
|
||||
try {
|
||||
const res = await connector.sendTransaction(params);
|
||||
|
||||
return res;
|
||||
console.log('res', res);
|
||||
} catch (err) {
|
||||
return {
|
||||
error: 'failed to send',
|
||||
};
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
store,
|
||||
connect,
|
||||
disconnect,
|
||||
sendTransaction,
|
||||
|
||||
get connectors() {
|
||||
return connectors.getState();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const config = createConfig({
|
||||
chains: [fairground, stagnet],
|
||||
connectors: [injected, jsonRpc, snap],
|
||||
});
|
||||
|
||||
function useWallet<T>(selector: (store: Store) => T) {
|
||||
const store = useStore(config.store, selector);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
function useConfig() {
|
||||
const context = useContext(VegaWalletContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('must be used within VegaWalletProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
function useConnect() {
|
||||
const config = useConfig();
|
||||
return {
|
||||
connectors: config.connectors,
|
||||
connect: config.connect,
|
||||
};
|
||||
}
|
||||
|
||||
function useDisconnect() {
|
||||
const config = useConfig();
|
||||
return {
|
||||
disconnect: config.disconnect,
|
||||
};
|
||||
}
|
||||
|
||||
function useSendTransaction() {
|
||||
const config = useConfig();
|
||||
return {
|
||||
sendTransaction: config.sendTransaction,
|
||||
};
|
||||
}
|
||||
|
||||
const VegaWalletContext = createContext<Wallet | undefined>(undefined);
|
||||
|
||||
function VegaWalletProvider({
|
||||
children,
|
||||
config,
|
||||
}: PropsWithChildren<{ config: Wallet }>) {
|
||||
return createElement(VegaWalletContext.Provider, { value: config }, children);
|
||||
}
|
||||
|
||||
export function Test() {
|
||||
return (
|
||||
<VegaWalletProvider config={config}>
|
||||
<App />
|
||||
</VegaWalletProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const { connectors, connect } = useConnect();
|
||||
const { disconnect } = useDisconnect();
|
||||
const { sendTransaction } = useSendTransaction();
|
||||
const status = useWallet((store) => store.status);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={() => setOpen(true)}>Connect</button>
|
||||
<Dialog open={open}>
|
||||
<div>
|
||||
{status === 'disconnected' && (
|
||||
<div className="flex gap-2">
|
||||
{connectors.map((c) => (
|
||||
<button
|
||||
key={c.id}
|
||||
onClick={async () => {
|
||||
try {
|
||||
await connect(c.id);
|
||||
setTimeout(() => {
|
||||
setOpen(false);
|
||||
}, 1000);
|
||||
} catch (err) {}
|
||||
}}
|
||||
>
|
||||
connect {c.id}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{status === 'connecting' && <div>Approve connection in wallet</div>}
|
||||
{status === 'connected' && <div>Connected!</div>}
|
||||
</div>
|
||||
</Dialog>
|
||||
<hr className="border-t pt-2 mt-2" />
|
||||
<div className="flex flex-col items-start gap-2">
|
||||
<button onClick={() => disconnect()}>diconnectWallet</button>
|
||||
<button
|
||||
onClick={async () => {
|
||||
const fromKey =
|
||||
'846b2ed2fff0ddf219a5302a3856f9ac279652c4d92e72e7df762117886e69cc'; // snap
|
||||
const toKey =
|
||||
'5a703397f6ac1f62513af1f5d0237d1b9f8b2c93ef19fbe9fa87771a2b7f55da'; // browser
|
||||
|
||||
const res = await sendTransaction({
|
||||
publicKey: fromKey,
|
||||
sendingMode: 'TYPE_SYNC',
|
||||
transaction: {
|
||||
transfer: {
|
||||
fromAccountType: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
to: toKey,
|
||||
toAccountType: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset:
|
||||
'16ae5dbb1fd7aa2ddef725703bfe66b3647a4da7b844bfdd04e985756f53d9d6',
|
||||
amount: '100',
|
||||
oneOff: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
console.log(res);
|
||||
}}
|
||||
>
|
||||
submit transfer
|
||||
</button>
|
||||
</div>
|
||||
<div>{status}</div>
|
||||
<Keys />
|
||||
{/* <NoReact /> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Keys = () => {
|
||||
const keys = useWallet((store) => store.keys);
|
||||
|
||||
if (!keys.length) {
|
||||
return <p>No keys</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{keys.map((k) => {
|
||||
return (
|
||||
<li key={k.publicKey}>
|
||||
{k.name} {k.publicKey}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
const NoReact = () => {
|
||||
const divRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!divRef.current) return;
|
||||
const div = divRef.current;
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.addEventListener('click', () => {
|
||||
config.connect('injected'); // should fail
|
||||
});
|
||||
button.textContent = 'Connect injected';
|
||||
|
||||
const status = document.createElement('div');
|
||||
const keys = document.createElement('ul');
|
||||
|
||||
config.store.subscribe((state) => {
|
||||
status.textContent = state.status;
|
||||
|
||||
state.keys.forEach((key) => {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = `${key.name} ${key.publicKey}`;
|
||||
keys.appendChild(li);
|
||||
});
|
||||
});
|
||||
|
||||
div.appendChild(button);
|
||||
div.appendChild(status);
|
||||
div.appendChild(keys);
|
||||
}, []);
|
||||
return (
|
||||
<div>
|
||||
<h1>No react</h1>
|
||||
<div ref={divRef} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
import { InjectedConnector } from './injected-connector';
|
||||
import { JsonRpcConnector } from './json-rpc-connector';
|
||||
import { SnapConnector } from './snap-connector';
|
||||
|
||||
export class Wallet {
|
||||
connector?: InjectedConnector | JsonRpcConnector | SnapConnector;
|
||||
|
||||
async connectWallet(
|
||||
connector: InjectedConnector | JsonRpcConnector | SnapConnector
|
||||
) {
|
||||
this.connector = connector;
|
||||
|
||||
const res = await this.connector.connectWallet();
|
||||
|
||||
if (res.success !== true) {
|
||||
// TODO: something better
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = await this.connector.listKeys();
|
||||
console.log(keys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
async disconnectWallet() {
|
||||
if (!this.connector) {
|
||||
throw new Error('no connector');
|
||||
}
|
||||
|
||||
await this.connector.disconnectWallet();
|
||||
this.connector = undefined;
|
||||
}
|
||||
|
||||
async listKeys() {
|
||||
if (!this.connector) {
|
||||
throw new Error('no connector');
|
||||
}
|
||||
|
||||
return this.connector.listKeys();
|
||||
}
|
||||
|
||||
async getChainId() {
|
||||
if (!this.connector) {
|
||||
throw new Error('no connector');
|
||||
}
|
||||
|
||||
return this.connector.getChainId();
|
||||
}
|
||||
|
||||
async isConnected() {
|
||||
if (!this.connector) {
|
||||
throw new Error('no connector');
|
||||
}
|
||||
|
||||
return this.connector.isConnected();
|
||||
}
|
||||
|
||||
// sendTransaction(...args: Parameters<typeof window.vega.sendTransaction>) {
|
||||
// if (!this.connector) {
|
||||
// throw new Error('no connector');
|
||||
// }
|
||||
//
|
||||
// return this.connector.sendTransaction(...args);
|
||||
// }
|
||||
}
|
||||
@@ -37,7 +37,9 @@ declare global {
|
||||
}>;
|
||||
|
||||
on: (event: VegaWalletEvent, callback: () => void) => void;
|
||||
isConnected?: () => Promise<boolean>;
|
||||
off: (event: VegaWalletEvent) => void;
|
||||
isConnected: () => Promise<boolean>;
|
||||
getChainId: () => Promise<{ chainID: string }>;
|
||||
}
|
||||
|
||||
interface Window {
|
||||
|
||||
Reference in New Issue
Block a user