Skip to content

Commit

Permalink
Add support for WalletConnect v2
Browse files Browse the repository at this point in the history
- add workspaces to root `package.json` so we can test demo app with
  local loader package without manual linking
- moved `checkSupport` parameter types and their management to a
  `supportOptions` module, added parameters for WalletConnect v2, sets
  defaults for chain parameters, `getSupportOptions` is called by other
  modules
- renamed `ExtensionUnavailableModal` to `ExtensionInstallModal`
- renamed `ConnectWithLedgerLiveModal` to `UseLedgerLiveModal`
- renamed the `Ethereum` provider to `ExtensionEvm` since it is used for
  Polygon and future EVM chains, moved chain compatibility checks there,
  renamed related constants and types
- renamed `Solana` to `ExtensionSolana` since this is through the
  extension, and we might support Solana through WalletConnect as well in
  the future
- renamed the original `WalletConnect` module to `WalletConnectLegacy`
  which now imports the dist file from `@walletconnect/legacy-provider`,
  updated the module declaration in `src/@types/index.d.ts`
- created a new `WalletConnectEvm` module for the v2 provider which
  imports the dist file from `@walletconnect/ethereum-provider` v2, added
  a new module declaration in `src/@types/index.d.ts`
- removed the `TryConnectEthereum` module
    - when the extension is supported but not installed we now default
      to the `WalletConnect` provider instead of the extension one, this
      will make it possible to use WC in that case if the user needs it
    - the modal module now has a `showExtensionOrLLModal` function with
      the logic to show the `ExtensionInstallModal` if both the user's
      platform and the required chains are supported, or the
      `UseLedgerLiveModal` one
    - the `eth_requestAccounts` request on both WalletConnect provider
      modules now call `showExtensionOrLLModal`
- `getProvider` now returns the `WalletConnectLegacy` provider if the
  version parameter is 1 or the `WalletConnectEvm` one otherwise
- store result of `checkSupport` in a module variable and make it
  available through `getSupportResult`, is used by
  `showExtensionOrLLModal` to decide which modal to show
- made some changes to the rollup config to be able to bundle
  @walletconnect/ethereum-provider v2
  • Loading branch information
hlopes-ledger committed Mar 1, 2023
1 parent acca935 commit 89e3d61
Show file tree
Hide file tree
Showing 27 changed files with 732 additions and 351 deletions.
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "connect-kit",
"private": true,
"workspaces": {
"packages": [
"packages/*"
]
}
}
9 changes: 5 additions & 4 deletions packages/connect-kit-loader/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@ledgerhq/connect-kit-loader",
"version": "1.0.2",
"description": "Load Ledger Connect Kit at runtime, a library for dapps to integrate with Ledger Connect and Ledger Live",
"author": "Hugo Lopes",
"version": "1.1.0-beta.1",
"description": "Load Ledger Connect Kit at runtime, a library for dapps to integrate with the Ledger Extension and Ledger Live",
"author": "Ledger SAS <ledger.com>",
"license": "MIT",
"keywords": [
"ledger",
Expand Down Expand Up @@ -39,6 +39,7 @@
"rollup": "^2.75.6",
"rollup-plugin-terser": "^7.0.2",
"tslib": "^2.4.0",
"typescript": "^4.7.3"
"typescript": "^4.7.3",
"@walletconnect/types": "^2.3.2"
}
}
18 changes: 17 additions & 1 deletion packages/connect-kit-loader/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { CoreTypes } from '@walletconnect/types';

// chain

export enum SupportedProviderImplementations {
Expand All @@ -12,7 +14,21 @@ export type EnableDebugLogsFunction = () => void;
// support

export type CheckSupportOptions = {
version?: number;
providerType: SupportedProviders;

// WalletConnect v2 init parameters
projectId?: string; // REQUIRED WC v2 project id, throws if v2 and not set
chains?: number[]; // REQUIRED ethereum chains, has default
optionalChains?: number[]; // OPTIONAL ethereum chains
methods?: string[]; // REQUIRED ethereum methods, has default
optionalMethods?: string[]; // OPTIONAL ethereum methods
events?: string[]; // REQUIRED ethereum events, has default
optionalEvents?: string[]; // OPTIONAL ethereum events
rpcMap?: { [chainId: string]: string; }; // OPTIONAL rpc urls for each chain
metadata?: CoreTypes.Metadata; // OPTIONAL metadata of your app

// WalletConnect v1 init parameters
chainId?: number;
bridge?: string;
infuraId?: string;
Expand All @@ -37,7 +53,7 @@ export type EthereumRequestPayload = {

export interface EthereumProvider {
providers?: EthereumProvider[];
connector?: unknown,
connector?: unknown;
request<T = unknown>(args: EthereumRequestPayload): Promise<T>;
disconnect?: {(): Promise<void>};
emit(eventName: string | symbol, ...args: any[]): boolean;
Expand Down
33 changes: 20 additions & 13 deletions packages/connect-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "@ledgerhq/connect-kit",
"version": "1.0.11",
"description": "A library for dapps to integrate with Ledger Connect and Ledger Live",
"author": "Hugo Lopes",
"version": "1.1.0-beta.1",
"description": "A library for dapps to integrate with the Ledger Extension and Ledger Live",
"author": "Ledger SAS <ledger.com>",
"license": "MIT",
"main": "dist/umd/index.js",
"module": "dist/umd/index.js",
"module": "dist/esm/index.js",
"files": [
"dist"
],
Expand All @@ -24,25 +24,32 @@
"devDependencies": {
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-image": "^2.1.1",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.3",
"@types/react": "^18.0.13",
"@types/react-dom": "^18.0.5",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/styled-components": "^5.1.25",
"bowser": "^2.11.0",
"@walletconnect/types": "^2.3.2",
"rollup": "^2.75.6",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-dts": "^4.2.2",
"rollup-plugin-polyfill-node": "^0.12.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-url-resolve": "^0.2.0",
"tslib": "^2.4.0",
"typescript": "^4.7.3"
},
"dependencies": {
"@walletconnect/ethereum-provider": "^1.8.0",
"typescript": "^4.7.3",
"@walletconnect/ethereum-provider": "^2.3.2",
"@walletconnect/legacy-provider": "^2.0.0",
"bowser": "^2.11.0",
"events": "^3.3.0",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"rollup-plugin-worker-factory": "^0.5.7",
"styled-components": "^5.3.5"
},
"dependencies": {
}
}
14 changes: 11 additions & 3 deletions packages/connect-kit/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import dts from "rollup-plugin-dts";
import image from '@rollup/plugin-image';
import replace from '@rollup/plugin-replace';
import { terser } from "rollup-plugin-terser";
import json from '@rollup/plugin-json';
import nodePolyfills from 'rollup-plugin-polyfill-node';

const packageJson = require("./package.json");

Expand All @@ -13,21 +15,27 @@ export default [
input: "src/index.ts",
output: [
{
file: packageJson.module,
exports: "named",
file: packageJson.main,
format: "umd",
sourcemap: true,
inlineDynamicImports: true,
name: "ledgerConnectKit",
sourcemap: true,
},
],
plugins: [
resolve({
preferBuiltins: false
}),
commonjs(),
commonjs({
transformMixedEsModules: true,
}),
nodePolyfills(),
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
preventAssignment: true,
}),
json(),
typescript({ tsconfig: "./tsconfig.json" }),
image(),
terser(),
Expand Down
13 changes: 9 additions & 4 deletions packages/connect-kit/src/@types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
declare module '@walletconnect/ethereum-provider/dist/umd/index.min.js' {
import WalletConnectProvider from '@walletconnect/ethereum-provider/dist/esm/index';
export default WalletConnectProvider;
}
declare module '@walletconnect/ethereum-provider/dist/index.umd.js' {
import WalletConnectProvider from '@walletconnect/ethereum-provider/dist/index.umd.js';
export default WalletConnectProvider
};

declare module '@walletconnect/legacy-provider/dist/umd/index.min.js' {
import WalletConnectProvider from '@walletconnect/legacy-provider/dist/umd/index.min.js';
export default WalletConnectProvider
};

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import {
ModalSection,
ModalTitle,
} from "../Modal/Modal.styles";
import { ConnectFeature } from "./ExtensionUnavailableModal.styles";
import { ConnectFeature } from "./ExtensionInstallModal.styles";
import { default as LightbulbSvg } from "../../assets/svg/Lightbulb.svg";
import { default as CheckmarkSvg } from "../../assets/svg/Checkmark.svg";
import NeedALedgerSection from "../NeedALedgerSection";
import { getDebugLogger } from "../../lib/logger";

const log = getDebugLogger('ExtensionUnavailableModal')
const log = getDebugLogger('ExtensionInstallModal')

export type ExtensionUnavailableModalProps = ModalProps;
export type ExtensionInstallModalProps = ModalProps;

const ExtensionUnavailableModal = ({
const ExtensionInstallModal = ({
onClose = () => void 0,
}: ExtensionUnavailableModalProps) => {
}: ExtensionInstallModalProps) => {
log('initializing');

const onJoinBetaClick = () => {
Expand Down Expand Up @@ -45,4 +45,4 @@ const ExtensionUnavailableModal = ({
);
};

export default ExtensionUnavailableModal;
export default ExtensionInstallModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./ExtensionInstallModal";

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { getDebugLogger } from "../../lib/logger";
import Modal, { ModalProps, setIsModalOpen } from "../Modal/Modal";
import {
Expand All @@ -7,26 +8,49 @@ import {
ModalTitle,
Link,
} from "../Modal/Modal.styles";
import { QrCode, QrCodeSection } from "./ConnectWithLedgerLiveModal.styles";
import { QrCode, QrCodeSection } from "./UseLedgerLiveModal.styles";

const log = getDebugLogger('ConnectWithLedgerLiveModal');
const log = getDebugLogger('UseLedgerLiveModal');

export type ConnectWithLedgerLiveModalProps = {
// placeholder functions until the component is initialized
let setModalUri = (uri: string) => {};

// called by the WalletConnect display_uri event handler to set a new URI
export let setWalletConnectUri = (uri: string): void => {
log('setModalUri', uri);
setModalUri(uri);
}

export type UseLedgerLiveModalProps = {
withQrCode?: boolean;
uri?: string;
} & ModalProps;

const ConnectWithLedgerLiveModal = ({
const UseLedgerLiveModal = ({
withQrCode = false,
uri = '',
onClose = () => void 0,
}: ConnectWithLedgerLiveModalProps) => {
}: UseLedgerLiveModalProps) => {
log('initializing', { withQrCode, uri });

const ledgerLiveDeepLink = `ledgerlive://wc?uri=${encodeURIComponent(uri)}`;
// use the uri prop as the initial start value
const [wcUri, setWcUri] = useState<string>(uri);
// replace the placeholder function by the setState one
setModalUri = setWcUri;
// update state only if supplied URI is different from previous and current
const previousUriRef = useRef<string>();
const previousUri = previousUriRef.current;
if (uri !== previousUri && uri !== wcUri) {
setWcUri(uri);
}
// update the previous URI ref on each rerender
useEffect(() => {
previousUriRef.current = uri;
});

const onUseLedgerLiveClick = () => {
window.location.href = ledgerLiveDeepLink;
log('loading Ledger Live, ', wcUri);
window.location.href = `ledgerlive://wc?uri=${encodeURIComponent(wcUri)}`;

// close the modal so that the current WalletConnect URI cannot be reused
setIsModalOpen(false);
Expand All @@ -44,14 +68,14 @@ const ConnectWithLedgerLiveModal = ({
<ModalSection textAlign="center">
<ModalTitle>Do you have Ledger Live?</ModalTitle>

{withQrCode && ledgerLiveDeepLink !== '' &&
{withQrCode && wcUri !== '' &&
<>
<ModalText>
Scan with your mobile.
</ModalText>

<QrCodeSection>
<QrCode value={ledgerLiveDeepLink} size={310} />
<QrCode value={wcUri} size={310} />
</QrCodeSection>

<ModalText noMargin>or</ModalText>
Expand All @@ -62,7 +86,7 @@ const ConnectWithLedgerLiveModal = ({
</>
}

{!withQrCode && ledgerLiveDeepLink !== '' &&
{!withQrCode && wcUri !== '' &&
<ModalButton variant="primary" onClick={onUseLedgerLiveClick} extraMargin>
Open Ledger Live
</ModalButton>
Expand All @@ -76,4 +100,4 @@ const ConnectWithLedgerLiveModal = ({
);
};

export default ConnectWithLedgerLiveModal;
export default UseLedgerLiveModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./UseLedgerLiveModal";
4 changes: 2 additions & 2 deletions packages/connect-kit/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { default as ExtensionUnavailableModal } from "./ExtensionUnavailableModal";
export { default as ConnectWithLedgerLiveModal } from "./ConnectWithLedgerLiveModal";
export { default as ExtensionInstallModal } from "./ExtensionInstallModal";
export { default as UseLedgerLiveModal } from "./UseLedgerLiveModal";
export { default as PlatformNotSupportedModal } from "./PlatformNotSupportedModal";
9 changes: 0 additions & 9 deletions packages/connect-kit/src/lib/connectSupport.ts

This file was deleted.

Loading

0 comments on commit 89e3d61

Please sign in to comment.