Skip to content

Commit

Permalink
feat: Connect using Leap Wallet support
Browse files Browse the repository at this point in the history
  • Loading branch information
Himanshu Singh authored and Himanshu Singh committed Oct 17, 2023
1 parent 2c97d8f commit befb534
Show file tree
Hide file tree
Showing 32 changed files with 2,962 additions and 2,516 deletions.
42 changes: 23 additions & 19 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import React, { lazy, Suspense, useEffect } from 'react';
import './style/app.css';
import { BrowserRouter as Router, Route, Routes, useNavigate } from 'react-router-dom';
import SideNav from './components/SideNav';
import Keplr from './components/KeplrLogin';
import Wallet from './components/WalletLogin';
import Logging from './components/Logging';
import Stack from '@mui/material/Stack';
import { useRecoilState } from 'recoil';
import { activeCertificate, keplrState } from './recoil/atoms';
import { getKeplr } from './_helpers/keplr-utils';
import { activeCertificate, walletState } from './recoil/atoms';
import { loadActiveCertificate } from './recoil/api';
import { useWallet } from './hooks/useWallet';
import Loading from './components/Loading';
import { getRpcNode, useRpcNode } from './hooks/useRpcNode';
import { useRpcNode } from './hooks/useRpcNode';
import { getWallet } from './_helpers/wallet-utils';

// Lazy loading all pages in appropriate time
const DeploymentStepper = lazy(() => import('./components/DeploymentStepper'));
Expand Down Expand Up @@ -76,7 +76,7 @@ const AppRouter = () => {
};

export default function App() {
const [keplr, setKeplr] = useRecoilState(keplrState);
const [wallet, setWallet] = useRecoilState(walletState);
const [certificate, setCertificate] = useRecoilState(activeCertificate);
const { isConnected } = useWallet();
const [getRpc] = useRpcNode();
Expand All @@ -85,43 +85,47 @@ export default function App() {
useEffect(() => {
let timer: NodeJS.Timeout | null = null;

const checkKeplr = async () => {

if (isConnected && window.keplr && keplr.accounts.length > 0 && keplr.accounts[0].address) {
const wallet = window.keplr.getOfflineSigner(rpcNode.chainId);
const checkWallet = async () => {
if (
isConnected &&
window.wallet &&
wallet.accounts.length > 0 &&
wallet.accounts[0].address
) {
const _wallet = window.wallet.getOfflineSigner(rpcNode.chainId);

try {
const accounts = await wallet.getAccounts();
const accounts = await _wallet.getAccounts();

// if the wallet's changed, update the atom
if (accounts[0].address !== keplr.accounts[0].address) {
setKeplr(await getKeplr());
if (accounts[0].address !== wallet.accounts[0].address) {
setWallet(await getWallet());
setCertificate(await loadActiveCertificate(accounts[0].address));
} else if (certificate.$type === 'Invalid Certificate') {
const activeCert = await loadActiveCertificate(keplr.accounts[0].address);
const activeCert = await loadActiveCertificate(wallet.accounts[0].address);

if (activeCert.$type === 'TLS Certificate') {
setCertificate(activeCert);
}
}
} catch (err) {
console.warn('unable to update keplr status', err);
console.warn('unable to update wallet status', err);
}
}

// schedule next check
timer = setTimeout(checkKeplr, 2000);
timer = setTimeout(checkWallet, 2000);
};

// start polling
checkKeplr();
checkWallet();

return () => {
if (timer) {
clearTimeout(timer);
}
};
}, [isConnected, certificate, setCertificate, keplr, setKeplr]);
}, [isConnected, certificate, setCertificate, wallet, setWallet]);

return (
<Logging>
Expand All @@ -132,9 +136,9 @@ export default function App() {
</Stack>
}
>
<Keplr>
<Wallet>
<AppRouter />
</Keplr>
</Wallet>
</Suspense>
</Logging>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
import { SigningCosmosClient } from '@cosmjs/launchpad';
import { KeplrWallet } from '../recoil/atoms';
import { Wallet } from '../recoil/atoms';
import { getRpcNode } from '../hooks/useRpcNode';
import { Wallets } from '../hooks/useWallet';

const initalState = {
accounts: [],
offlineSigner: undefined,
cosmosClient: undefined,
isSignedIn: false,
file: '_helpers/keplr-utils.ts',
isSignedIn: '',
file: '_helpers/wallet-utils.ts',
};

export const getKeplr = async (): Promise<KeplrWallet> => {
export const getWallet = async (): Promise<Wallet> => {
const { chainId, rpcNode } = getRpcNode();

if (!window.keplr) {
if (!window.wallet) {
return initalState;
} else {
// Enabling before using the Keplr is recommended.
// Enabling before using the Wallet is recommended.
// This method will ask the user whether to allow access if they haven't visited this website.
// Also, it will request that the user unlock the wallet if the wallet is locked.
await window.keplr.enable(chainId);
await window.wallet.enable(chainId);

const offlineSigner = window.keplr.getOfflineSigner(chainId);
const offlineSigner = window.wallet.getOfflineSigner(chainId);

// You can get the address/public keys by `getAccounts` method.
// It can return the array of address/public key.
// But, currently, Keplr extension manages only one address/public key pair.
// But, currently, Leap and Keplr extension manages only one address/public key pair.
// XXX: This line is needed to set the sender address for SigningCosmosClient.
const accounts = await offlineSigner.getAccounts();

// Initialize the gaia api with the offline signer that is injected by Keplr extension.
// Initialize the gaia api with the offline signer that is injected by Leap/Keplr extension.
const cosmJS = new SigningCosmosClient(rpcNode, accounts[0].address, offlineSigner);

return {
accounts: [...accounts],
offlineSigner: offlineSigner,
cosmosClient: cosmJS,
isSignedIn: true,
file: '_helpers/keplr-utils.ts',
isSignedIn: window.wallet.constructor.name === 'Leap' ? Wallets.LEAP : Wallets.KEPLR,
file: '_helpers/wallet-utils.ts',
};
}
};
101 changes: 60 additions & 41 deletions web/src/api/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,77 @@ import { getRpcNode } from '../hooks/useRpcNode';

import * as beta2 from './rpc/beta2';
import * as beta3 from './rpc/beta3';
import { getKeplr } from '../_helpers/keplr-utils';
import { getCurrentHeight } from '../_helpers/deployments-utils';
import { getWallet } from '../_helpers/wallet-utils';
import { SDLSpec } from '../components/SdlConfiguration/settings';

export const closeDeployment = async (dseq: string) => {
const { networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

const mutateMethod = networkType === 'testnet'
? beta3.deployments.closeDeployment
: beta2.deployments.closeDeployment;
const mutateMethod =
networkType === 'testnet'
? beta3.deployments.closeDeployment
: beta2.deployments.closeDeployment;

const owner = wallet.accounts[0].address;

return mutateMethod(wallet, { owner, dseq: parseInt(dseq) });
};

export const fundDeployment = async ({ dseq, amount }: { dseq: string, amount: number }) => {
export const fundDeployment = async ({ dseq, amount }: { dseq: string; amount: number }) => {
const { networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

const mutateMethod = networkType === 'testnet'
? beta3.deployments.fundDeployment
: beta2.deployments.fundDeployment;
const mutateMethod =
networkType === 'testnet' ? beta3.deployments.fundDeployment : beta2.deployments.fundDeployment;

const owner = wallet.accounts[0].address;

return mutateMethod(wallet, { owner, dseq: parseInt(dseq) }, amount);
};

export const createDeployment = async (
{ sdl, depositor }: { sdl: SDLSpec | undefined; depositor?: string }
) => {
export const createDeployment = async ({
sdl,
depositor,
}: {
sdl: SDLSpec | undefined;
depositor?: string;
}) => {
const { networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

if (!sdl) {
return Promise.reject('No SDL provided');
}

const mutateMethod = networkType === 'testnet'
? beta3.deployments.createDeployment
: beta2.deployments.createDeployment;
const mutateMethod =
networkType === 'testnet'
? beta3.deployments.createDeployment
: beta2.deployments.createDeployment;

return mutateMethod(wallet, sdl, depositor);
};

export const createCertificate = async () => {
const { rpcNode, networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

const mutateMethod = networkType === 'testnet'
? beta3.certificates.createAndBroadcastCertificate
: beta2.certificates.createAndBroadcastCertificate;
const mutateMethod =
networkType === 'testnet'
? beta3.certificates.createAndBroadcastCertificate
: beta2.certificates.createAndBroadcastCertificate;

return mutateMethod(rpcNode, wallet);
};

export const revokeCertificate = async (certificate: string) => {
const { rpcNode, networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

const mutateMethod = networkType === 'testnet'
? beta3.certificates.broadcastRevokeCertificate
: beta2.certificates.broadcastRevokeCertificate;
const mutateMethod =
networkType === 'testnet'
? beta3.certificates.broadcastRevokeCertificate
: beta2.certificates.broadcastRevokeCertificate;

return mutateMethod(rpcNode, wallet, certificate);
};
Expand All @@ -79,36 +85,49 @@ export const createLease = async (bidId: {
provider: string;
}) => {
const { networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

const mutateMethod = networkType === 'testnet'
? beta3.deployments.createLease
: beta2.deployments.createLease;
const mutateMethod =
networkType === 'testnet' ? beta3.deployments.createLease : beta2.deployments.createLease;

return mutateMethod(wallet, (bidId as any));
return mutateMethod(wallet, bidId as any);
};

export const sendManifest = async ({ address, lease, sdl }: { address: string, lease: any, sdl: any }) => {
export const sendManifest = async ({
address,
lease,
sdl,
}: {
address: string;
lease: any;
sdl: any;
}) => {
const { networkType } = getRpcNode();

const mutateMethod = networkType === 'testnet'
? beta3.deployments.sendManifest
: beta2.deployments.sendManifest;
const mutateMethod =
networkType === 'testnet' ? beta3.deployments.sendManifest : beta2.deployments.sendManifest;

return mutateMethod(address, lease, sdl);
};

export const updateDeployment = async ({ deploymentId, sdl }: { deploymentId: object, sdl: SDLSpec | undefined }) => {
export const updateDeployment = async ({
deploymentId,
sdl,
}: {
deploymentId: object;
sdl: SDLSpec | undefined;
}) => {
const { networkType } = getRpcNode();
const wallet = await getKeplr();
const wallet = await getWallet();

if (!sdl) {
return Promise.reject('No SDL provided');
}

const mutateMethod = networkType === 'testnet'
? beta3.deployments.updateDeployment
: beta2.deployments.updateDeployment;
const mutateMethod =
networkType === 'testnet'
? beta3.deployments.updateDeployment
: beta2.deployments.updateDeployment;

return mutateMethod(wallet, deploymentId, sdl);
};
};
7 changes: 4 additions & 3 deletions web/src/api/rpc/beta2/certificates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,18 @@ export const getCertificateByIndex = (

export const loadActiveCertificateAuto = async () => {
const rpcNode = getRpcNode();
const accounts = await window.keplr?.getOfflineSigner(rpcNode.chainId).getAccounts();

const accounts = await window.wallet?.getOfflineSigner(rpcNode.chainId).getAccounts();
const walletId = accounts?.[0].address;

if (!walletId) {
throw new Error('Unable to fetch active certificate. Unable to determine wallet ID.');
// return { $type: 'Invalid Certificate' };
// throw new Error('Unable to fetch active certificate. Unable to determine wallet ID.');
}

return loadActiveCertificate(walletId);
};


export const loadActiveCertificate = async (walletId: string) => {
if (!walletId) {
return { $type: 'Invalid Certificate' } as NoCertificate;
Expand Down
Loading

0 comments on commit befb534

Please sign in to comment.