diff --git a/apps/sample-next-app/tsconfig.json b/examples/sample-next-app/tsconfig.json
similarity index 100%
rename from apps/sample-next-app/tsconfig.json
rename to examples/sample-next-app/tsconfig.json
diff --git a/apps/sample-react-app/.eslintrc.cjs b/examples/sample-react-app/.eslintrc.cjs
similarity index 100%
rename from apps/sample-react-app/.eslintrc.cjs
rename to examples/sample-react-app/.eslintrc.cjs
diff --git a/apps/sample-react-app/.gitignore b/examples/sample-react-app/.gitignore
similarity index 100%
rename from apps/sample-react-app/.gitignore
rename to examples/sample-react-app/.gitignore
diff --git a/apps/sample-react-app/README.md b/examples/sample-react-app/README.md
similarity index 100%
rename from apps/sample-react-app/README.md
rename to examples/sample-react-app/README.md
diff --git a/apps/sample-react-app/index.html b/examples/sample-react-app/index.html
similarity index 100%
rename from apps/sample-react-app/index.html
rename to examples/sample-react-app/index.html
diff --git a/apps/sample-react-app/package.json b/examples/sample-react-app/package.json
similarity index 100%
rename from apps/sample-react-app/package.json
rename to examples/sample-react-app/package.json
diff --git a/apps/sample-react-app/src/App.tsx b/examples/sample-react-app/src/App.tsx
similarity index 86%
rename from apps/sample-react-app/src/App.tsx
rename to examples/sample-react-app/src/App.tsx
index 6e403645..752817e5 100644
--- a/apps/sample-react-app/src/App.tsx
+++ b/examples/sample-react-app/src/App.tsx
@@ -7,7 +7,7 @@ import { useEffect, useState } from 'react';
function App() {
const { account } = useWallet();
- const { open, onConnected } = useWalletModal();
+ const { open, onConnectionStatusChange } = useWalletModal();
const [buttonText, setButtonText] = useState('Connect Custom Button');
useEffect(() => {
@@ -25,8 +25,8 @@ function App() {
handleConnected(account);
- onConnected(handleConnected);
- }, [account, onConnected]);
+ onConnectionStatusChange(handleConnected);
+ }, [account, onConnectionStatusChange]);
return (
diff --git a/apps/sample-react-app/src/index.css b/examples/sample-react-app/src/index.css
similarity index 100%
rename from apps/sample-react-app/src/index.css
rename to examples/sample-react-app/src/index.css
diff --git a/apps/sample-react-app/src/main.tsx b/examples/sample-react-app/src/main.tsx
similarity index 100%
rename from apps/sample-react-app/src/main.tsx
rename to examples/sample-react-app/src/main.tsx
diff --git a/apps/sample-react-app/src/vite-env.d.ts b/examples/sample-react-app/src/vite-env.d.ts
similarity index 100%
rename from apps/sample-react-app/src/vite-env.d.ts
rename to examples/sample-react-app/src/vite-env.d.ts
diff --git a/apps/sample-react-app/tsconfig.json b/examples/sample-react-app/tsconfig.json
similarity index 100%
rename from apps/sample-react-app/tsconfig.json
rename to examples/sample-react-app/tsconfig.json
diff --git a/apps/sample-react-app/tsconfig.node.json b/examples/sample-react-app/tsconfig.node.json
similarity index 100%
rename from apps/sample-react-app/tsconfig.node.json
rename to examples/sample-react-app/tsconfig.node.json
diff --git a/apps/sample-react-app/vite.config.ts b/examples/sample-react-app/vite.config.ts
similarity index 76%
rename from apps/sample-react-app/vite.config.ts
rename to examples/sample-react-app/vite.config.ts
index bcd3b212..5702ea65 100644
--- a/apps/sample-react-app/vite.config.ts
+++ b/examples/sample-react-app/vite.config.ts
@@ -4,6 +4,11 @@ import { nodePolyfills } from 'vite-plugin-node-polyfills';
export default defineConfig({
plugins: [nodePolyfills(), react()],
+ build: {
+ commonjsOptions: {
+ transformMixedEsModules: true,
+ },
+ },
base:
process.env.NODE_ENV === 'production'
? '/vechain-dapp-kit/react/'
diff --git a/apps/sample-svelte-app/.eslintignore b/examples/sample-svelte-app/.eslintignore
similarity index 100%
rename from apps/sample-svelte-app/.eslintignore
rename to examples/sample-svelte-app/.eslintignore
diff --git a/apps/sample-svelte-app/.eslintrc.cjs b/examples/sample-svelte-app/.eslintrc.cjs
similarity index 100%
rename from apps/sample-svelte-app/.eslintrc.cjs
rename to examples/sample-svelte-app/.eslintrc.cjs
diff --git a/apps/sample-svelte-app/.gitignore b/examples/sample-svelte-app/.gitignore
similarity index 100%
rename from apps/sample-svelte-app/.gitignore
rename to examples/sample-svelte-app/.gitignore
diff --git a/apps/sample-svelte-app/.npmrc b/examples/sample-svelte-app/.npmrc
similarity index 100%
rename from apps/sample-svelte-app/.npmrc
rename to examples/sample-svelte-app/.npmrc
diff --git a/apps/sample-svelte-app/.prettierignore b/examples/sample-svelte-app/.prettierignore
similarity index 100%
rename from apps/sample-svelte-app/.prettierignore
rename to examples/sample-svelte-app/.prettierignore
diff --git a/apps/sample-svelte-app/README.md b/examples/sample-svelte-app/README.md
similarity index 100%
rename from apps/sample-svelte-app/README.md
rename to examples/sample-svelte-app/README.md
diff --git a/apps/sample-svelte-app/package.json b/examples/sample-svelte-app/package.json
similarity index 100%
rename from apps/sample-svelte-app/package.json
rename to examples/sample-svelte-app/package.json
diff --git a/apps/sample-svelte-app/src/app.d.ts b/examples/sample-svelte-app/src/app.d.ts
similarity index 100%
rename from apps/sample-svelte-app/src/app.d.ts
rename to examples/sample-svelte-app/src/app.d.ts
diff --git a/apps/sample-svelte-app/src/app.html b/examples/sample-svelte-app/src/app.html
similarity index 100%
rename from apps/sample-svelte-app/src/app.html
rename to examples/sample-svelte-app/src/app.html
diff --git a/apps/sample-svelte-app/src/lib/index.ts b/examples/sample-svelte-app/src/lib/index.ts
similarity index 95%
rename from apps/sample-svelte-app/src/lib/index.ts
rename to examples/sample-svelte-app/src/lib/index.ts
index a45fda68..98f9f3dd 100644
--- a/apps/sample-svelte-app/src/lib/index.ts
+++ b/examples/sample-svelte-app/src/lib/index.ts
@@ -41,6 +41,6 @@ setTimeout(() => {
handleConnected(DAppKitUI.wallet.state.address);
- DAppKitUI.modal.onConnected(handleConnected);
+ DAppKitUI.modal.onConnectionStatusChange(handleConnected);
}
}, 100);
diff --git a/apps/sample-svelte-app/src/routes/+layout.js b/examples/sample-svelte-app/src/routes/+layout.js
similarity index 100%
rename from apps/sample-svelte-app/src/routes/+layout.js
rename to examples/sample-svelte-app/src/routes/+layout.js
diff --git a/apps/sample-svelte-app/src/routes/+page.svelte b/examples/sample-svelte-app/src/routes/+page.svelte
similarity index 100%
rename from apps/sample-svelte-app/src/routes/+page.svelte
rename to examples/sample-svelte-app/src/routes/+page.svelte
diff --git a/apps/sample-svelte-app/static/favicon.png b/examples/sample-svelte-app/static/favicon.png
similarity index 100%
rename from apps/sample-svelte-app/static/favicon.png
rename to examples/sample-svelte-app/static/favicon.png
diff --git a/apps/sample-svelte-app/svelte.config.js b/examples/sample-svelte-app/svelte.config.js
similarity index 100%
rename from apps/sample-svelte-app/svelte.config.js
rename to examples/sample-svelte-app/svelte.config.js
diff --git a/apps/sample-svelte-app/tsconfig.json b/examples/sample-svelte-app/tsconfig.json
similarity index 100%
rename from apps/sample-svelte-app/tsconfig.json
rename to examples/sample-svelte-app/tsconfig.json
diff --git a/apps/sample-svelte-app/vite.config.ts b/examples/sample-svelte-app/vite.config.ts
similarity index 100%
rename from apps/sample-svelte-app/vite.config.ts
rename to examples/sample-svelte-app/vite.config.ts
diff --git a/apps/sample-vanilla-app/index.html b/examples/sample-vanilla-app/index.html
similarity index 100%
rename from apps/sample-vanilla-app/index.html
rename to examples/sample-vanilla-app/index.html
diff --git a/apps/sample-vanilla-app/index.js b/examples/sample-vanilla-app/index.js
similarity index 95%
rename from apps/sample-vanilla-app/index.js
rename to examples/sample-vanilla-app/index.js
index e53aa5d7..4ed22d3a 100644
--- a/apps/sample-vanilla-app/index.js
+++ b/examples/sample-vanilla-app/index.js
@@ -42,4 +42,4 @@ const handleConnected = (address) => {
handleConnected(DAppKitUI.wallet.state.address);
-DAppKitUI.modal.onConnected(handleConnected);
+DAppKitUI.modal.onConnectionStatusChange(handleConnected);
diff --git a/apps/sample-vanilla-app/package.json b/examples/sample-vanilla-app/package.json
similarity index 100%
rename from apps/sample-vanilla-app/package.json
rename to examples/sample-vanilla-app/package.json
diff --git a/apps/sample-vue-app/.gitignore b/examples/sample-vue-app/.gitignore
similarity index 100%
rename from apps/sample-vue-app/.gitignore
rename to examples/sample-vue-app/.gitignore
diff --git a/apps/sample-vue-app/README.md b/examples/sample-vue-app/README.md
similarity index 100%
rename from apps/sample-vue-app/README.md
rename to examples/sample-vue-app/README.md
diff --git a/apps/sample-vue-app/babel.config.js b/examples/sample-vue-app/babel.config.js
similarity index 100%
rename from apps/sample-vue-app/babel.config.js
rename to examples/sample-vue-app/babel.config.js
diff --git a/apps/sample-vue-app/package.json b/examples/sample-vue-app/package.json
similarity index 100%
rename from apps/sample-vue-app/package.json
rename to examples/sample-vue-app/package.json
diff --git a/apps/sample-vue-app/public/favicon.ico b/examples/sample-vue-app/public/favicon.ico
similarity index 100%
rename from apps/sample-vue-app/public/favicon.ico
rename to examples/sample-vue-app/public/favicon.ico
diff --git a/apps/sample-vue-app/public/index.html b/examples/sample-vue-app/public/index.html
similarity index 100%
rename from apps/sample-vue-app/public/index.html
rename to examples/sample-vue-app/public/index.html
diff --git a/apps/sample-vue-app/src/App.vue b/examples/sample-vue-app/src/App.vue
similarity index 97%
rename from apps/sample-vue-app/src/App.vue
rename to examples/sample-vue-app/src/App.vue
index 7f84a5c3..c680a9ea 100644
--- a/apps/sample-vue-app/src/App.vue
+++ b/examples/sample-vue-app/src/App.vue
@@ -54,7 +54,7 @@ setTimeout(() => {
handleConnected(DAppKitUI.wallet.state.address);
- DAppKitUI.modal.onConnected(handleConnected);
+ DAppKitUI.modal.onConnectionStatusChange(handleConnected);
}
}, 100);
diff --git a/apps/sample-vue-app/src/main.ts b/examples/sample-vue-app/src/main.ts
similarity index 100%
rename from apps/sample-vue-app/src/main.ts
rename to examples/sample-vue-app/src/main.ts
diff --git a/apps/sample-vue-app/src/shims-vue.d.ts b/examples/sample-vue-app/src/shims-vue.d.ts
similarity index 100%
rename from apps/sample-vue-app/src/shims-vue.d.ts
rename to examples/sample-vue-app/src/shims-vue.d.ts
diff --git a/apps/sample-vue-app/tsconfig.json b/examples/sample-vue-app/tsconfig.json
similarity index 100%
rename from apps/sample-vue-app/tsconfig.json
rename to examples/sample-vue-app/tsconfig.json
diff --git a/apps/sample-vue-app/vue.config.js b/examples/sample-vue-app/vue.config.js
similarity index 100%
rename from apps/sample-vue-app/vue.config.js
rename to examples/sample-vue-app/vue.config.js
diff --git a/package.json b/package.json
index ba6d9173..5e2837e5 100755
--- a/package.json
+++ b/package.json
@@ -1,10 +1,11 @@
{
- "private": true,
"name": "vechain-dapp-kit",
+ "private": true,
"description": "A TypeScript library that facilitates seamless interaction between vechain wallets (veworld, sync2) and dApps.",
"workspaces": [
- "apps/*",
- "packages/*"
+ "examples/*",
+ "packages/*",
+ "tests/*"
],
"scripts": {
"build": "turbo run build",
diff --git a/packages/dapp-kit-react/README.md b/packages/dapp-kit-react/README.md
index d6ed34e6..f0c9772a 100644
--- a/packages/dapp-kit-react/README.md
+++ b/packages/dapp-kit-react/README.md
@@ -1,22 +1,9 @@
# `@vechain/dapp-kit-react`
-## Why ?
-
-- Allow easy interaction with all wallets.
-- Connex is designed to play nice with one wallet at a time, this library provides a layer on top of Connex to easily
- allow interaction with all wallets.
-- Easy setup for wallet connect
+The Vechain DApp Kit serves as a sophisticated layer built upon @vechain/connex, providing a simplified and efficient avenue for engaging with a multitude of Vechain wallets. This innovative toolkit enhances the ease of interaction, offering developers a seamless bridge to connect with diverse Vechain wallet functionalities. For more information, please refer to the official [Vechain Docs](https://docs.vechain.org/developer-resources/sdks-and-providers/dapp-kit)
## Installation
-### Build
-
-```bash
-yarn build
-```
-
-## Usage
-
```bash
yarn add @vechain/dapp-kit-react
```
diff --git a/packages/dapp-kit-react/package.json b/packages/dapp-kit-react/package.json
index c5a103e3..c22b627b 100644
--- a/packages/dapp-kit-react/package.json
+++ b/packages/dapp-kit-react/package.json
@@ -2,6 +2,8 @@
"name": "@vechain/dapp-kit-react",
"version": "1.0.0",
"private": false,
+ "homepage": "https://github.com/vechainfoundation/vechain-dapp-kit",
+ "repository": "github:vechain/vechain-dapp-kit",
"license": "MIT",
"sideEffects": false,
"type": "module",
diff --git a/packages/dapp-kit-react/src/DAppKitProvider.tsx b/packages/dapp-kit-react/src/DAppKitProvider.tsx
index e5ac8c05..530bf3d5 100644
--- a/packages/dapp-kit-react/src/DAppKitProvider.tsx
+++ b/packages/dapp-kit-react/src/DAppKitProvider.tsx
@@ -10,6 +10,7 @@ import type { WalletSource } from '@vechain/dapp-kit';
import { DAppKitUI } from '@vechain/dapp-kit-ui';
import { subscribeKey } from 'valtio/vanilla/utils';
import type { DAppKitProviderOptions, DAppKitContext } from './types';
+import { Certificate } from 'thor-devkit';
/**
* Context
@@ -23,6 +24,7 @@ export const DAppKitProvider: React.FC
= ({
walletConnectOptions,
usePersistence = false,
logLevel,
+ requireCertificate,
themeMode,
themeVariables,
i18n,
@@ -38,6 +40,7 @@ export const DAppKitProvider: React.FC = ({
walletConnectOptions,
usePersistence,
logLevel,
+ requireCertificate,
themeVariables,
themeMode,
i18n,
@@ -51,6 +54,7 @@ export const DAppKitProvider: React.FC = ({
walletConnectOptions,
usePersistence,
logLevel,
+ requireCertificate,
themeVariables,
themeMode,
i18n,
@@ -66,6 +70,8 @@ export const DAppKitProvider: React.FC = ({
const [source, setSource] = useState(
connex.wallet.state.source,
);
+ const [connectionCertificate, setConnectionCertificate] =
+ useState(connex.wallet.state.connectionCertificate);
useEffect(() => {
const addressSub = subscribeKey(connex.wallet.state, 'address', (v) => {
@@ -74,10 +80,18 @@ export const DAppKitProvider: React.FC = ({
const sourceSub = subscribeKey(connex.wallet.state, 'source', (v) => {
setSource(v);
});
+ const certificateSub = subscribeKey(
+ connex.wallet.state,
+ 'connectionCertificate',
+ (v) => {
+ setConnectionCertificate(v);
+ },
+ );
return () => {
addressSub();
sourceSub();
+ certificateSub();
};
}, [connex.wallet.state]);
@@ -90,7 +104,7 @@ export const DAppKitProvider: React.FC = ({
}, []);
const onModalConnected = useCallback(
(callback: (address: string | null) => void) =>
- DAppKitUI.modal.onConnected(callback),
+ DAppKitUI.modal.onConnectionStatusChange(callback),
[],
);
@@ -107,14 +121,23 @@ export const DAppKitProvider: React.FC = ({
availableWallets: connex.wallet.state.availableSources,
account,
source,
+ connectionCertificate,
},
modal: {
open: openModal,
close: closeModal,
- onConnected: onModalConnected,
+ onConnectionStatusChange: onModalConnected,
},
};
- }, [connex, account, source, closeModal, openModal, onModalConnected]);
+ }, [
+ connex,
+ account,
+ source,
+ closeModal,
+ openModal,
+ onModalConnected,
+ connectionCertificate,
+ ]);
return {children};
};
diff --git a/packages/dapp-kit-react/src/types.ts b/packages/dapp-kit-react/src/types.ts
index e4360227..e44a89e1 100644
--- a/packages/dapp-kit-react/src/types.ts
+++ b/packages/dapp-kit-react/src/types.ts
@@ -1,5 +1,6 @@
///
import type React from 'react';
+import type { Certificate } from 'thor-devkit';
import type { ConnectResponse, WalletSource } from '@vechain/dapp-kit';
import { type DAppKitUIOptions } from '@vechain/dapp-kit-ui';
@@ -34,10 +35,13 @@ export interface DAppKitContext {
connect: () => Promise;
account: string | null;
source: WalletSource | null;
+ connectionCertificate: Certificate | null;
};
modal: {
open: () => void;
close: () => void;
- onConnected: (callback: (address: string | null) => void) => void;
+ onConnectionStatusChange: (
+ callback: (address: string | null) => void,
+ ) => void;
};
}
diff --git a/packages/dapp-kit-ui/README.md b/packages/dapp-kit-ui/README.md
index 2491b0e6..8977a523 100644
--- a/packages/dapp-kit-ui/README.md
+++ b/packages/dapp-kit-ui/README.md
@@ -1,20 +1,6 @@
# `@vechain/dapp-kit-ui`
-## Why ?
-
-- Creating some reusable UI components for connecting wallets
-- Allow easy interaction with all wallets.
-- Connex is designed to play nice with one wallet at a time, this library provides a layer on top of Connex to easily
- allow interaction with all wallets.
-- Easy setup for wallet connect.
-
-## Installation
-
-### Build
-
-```bash
-yarn build
-```
+The Vechain DApp Kit serves as a sophisticated layer built upon @vechain/connex, providing a simplified and efficient avenue for engaging with a multitude of Vechain wallets. This innovative toolkit enhances the ease of interaction, offering developers a seamless bridge to connect with diverse Vechain wallet functionalities. For more information, please refer to the official [Vechain Docs](https://docs.vechain.org/developer-resources/sdks-and-providers/dapp-kit)
## Usage
diff --git a/packages/dapp-kit-ui/index.js b/packages/dapp-kit-ui/index.js
index 1a007f35..ae3b1910 100644
--- a/packages/dapp-kit-ui/index.js
+++ b/packages/dapp-kit-ui/index.js
@@ -42,4 +42,4 @@ const handleConnected = (address) => {
handleConnected(DAppKitUI.wallet.state.address);
-DAppKitUI.modal.onConnected(handleConnected);
+DAppKitUI.modal.onConnectionStatusChange(handleConnected);
diff --git a/packages/dapp-kit-ui/package.json b/packages/dapp-kit-ui/package.json
index 6bb0d6a2..5289a225 100644
--- a/packages/dapp-kit-ui/package.json
+++ b/packages/dapp-kit-ui/package.json
@@ -9,6 +9,8 @@
"typescript",
"lit"
],
+ "homepage": "https://github.com/vechainfoundation/vechain-dapp-kit",
+ "repository": "github:vechain/vechain-dapp-kit",
"license": "MIT",
"author": "Davide Carpini",
"type": "module",
diff --git a/packages/dapp-kit-ui/src/assets/styles/button.ts b/packages/dapp-kit-ui/src/assets/styles/button.ts
index 68ecfa71..f924698c 100644
--- a/packages/dapp-kit-ui/src/assets/styles/button.ts
+++ b/packages/dapp-kit-ui/src/assets/styles/button.ts
@@ -22,35 +22,42 @@ export const buttonStyle = css`
background: var(--vdk-color-light-primary, ${Colors.Light.Primary});
color: var(--vdk-color-light-tertiary, ${Colors.Light.Tertiary});
}
- button.LIGHT:hover {
+ button.LIGHT:hover:not(:disabled) {
background: var(
--vdk-color-light-primary-hover,
${Colors.Light.PrimaryHover}
);
}
- button.LIGHT:active {
+ button.LIGHT:active:not(:disabled) {
background: var(
--vdk-color-light-primary-active,
${Colors.Light.PrimaryActive}
);
}
+ button.LIGHT:disabled {
+ opacity: 0.8;
+ }
button.DARK {
background: var(--vdk-color-dark-primary, ${Colors.Dark.Primary});
color: var(--vdk-color-dark-tertiary, ${Colors.Dark.Tertiary});
}
- button.DARK:hover {
+ button.DARK:hover:not(:disabled) {
background: var(
--vdk-color-dark-primary-hover,
${Colors.Dark.PrimaryHover}
);
}
- button.DARK:active {
+ button.DARK:active:not(:disabled) {
background: var(
--vdk-color-dark-primary-active,
${Colors.Dark.PrimaryActive}
);
}
+
+ button.DARK:disabled {
+ opacity: 0.8;
+ }
`;
export const iconButtonStyle = css`
@@ -83,4 +90,8 @@ export const iconButtonStyle = css`
.icon-button.DARK:active {
background: var(--vdk-color-dark-primary, ${Colors.Dark.PrimaryActive});
}
+
+ button:disabled {
+ opacity: 0.8;
+ }
`;
diff --git a/packages/dapp-kit-ui/src/class/index.ts b/packages/dapp-kit-ui/src/class/index.ts
deleted file mode 100644
index df34a59e..00000000
--- a/packages/dapp-kit-ui/src/class/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './responsive';
diff --git a/packages/dapp-kit-ui/src/class/responsive.ts b/packages/dapp-kit-ui/src/class/responsive.ts
deleted file mode 100644
index b6727843..00000000
--- a/packages/dapp-kit-ui/src/class/responsive.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { LitElement } from 'lit';
-import { property } from 'lit/decorators';
-import { addResizeListeners } from '../utils';
-import { Breakpoint } from '../constants';
-
-export enum Media {
- Mobile = 'mobile',
- Tablet = 'tablet',
- Desktop = 'desktop',
-}
-
-export class ResponsiveLitElement extends LitElement {
- @property()
- media = Media.Desktop;
-
- private setCurrentMedia = (): void => {
- if (window.screen.width <= Breakpoint.Mobile) {
- this.media = Media.Mobile;
- return;
- }
- if (window.screen.width <= Breakpoint.Tablet) {
- this.media = Media.Tablet;
- return;
- }
- this.media = Media.Desktop;
- };
-
- constructor() {
- super();
- addResizeListeners(this.setCurrentMedia);
- }
-}
diff --git a/packages/dapp-kit-ui/src/classes/connect-modal-manager.ts b/packages/dapp-kit-ui/src/classes/connect-modal-manager.ts
new file mode 100644
index 00000000..0f5d1300
--- /dev/null
+++ b/packages/dapp-kit-ui/src/classes/connect-modal-manager.ts
@@ -0,0 +1,72 @@
+import type { WalletManager, WalletSource } from '@vechain/dapp-kit';
+import { DAppKitLogger } from '@vechain/dapp-kit';
+import { subscribeKey } from 'valtio/vanilla/utils';
+import { createModalIfNotPresent, dispatchCustomEvent } from '../utils';
+
+export interface ConnectModalManagerOptions {
+ modalParent?: HTMLElement;
+}
+
+export class ConnectModalManager {
+ private static instance: ConnectModalManager | null = null;
+
+ private constructor(
+ private walletManager: WalletManager,
+ options?: ConnectModalManagerOptions,
+ ) {
+ createModalIfNotPresent(options);
+ }
+
+ public static getInstance(
+ walletManager: WalletManager,
+ options?: ConnectModalManagerOptions,
+ ): ConnectModalManager {
+ if (!ConnectModalManager.instance) {
+ ConnectModalManager.instance = new ConnectModalManager(
+ walletManager,
+ options,
+ );
+ }
+
+ return ConnectModalManager.instance;
+ }
+
+ open(): void {
+ DAppKitLogger.debug('ConnectModalManager', 'opening the modal');
+ dispatchCustomEvent('vdk-open-wallet-modal');
+ }
+
+ close(): void {
+ DAppKitLogger.debug('ConnectModalManager', 'closing the modal');
+ dispatchCustomEvent('vdk-close-wallet-modal');
+ }
+
+ closeWalletConnect(): void {
+ DAppKitLogger.debug('ConnectModalManager', 'closing wallet connect');
+ dispatchCustomEvent('vdk-close-wc-qrcode');
+ }
+
+ closeConnectionCertificateRequest(): void {
+ DAppKitLogger.debug(
+ 'ConnectModalManager',
+ 'closing connection certificate request',
+ );
+ dispatchCustomEvent('vdk-close-connection-certificate-request');
+ }
+
+ onConnectionStatusChange(
+ callback: (address: string | null) => void,
+ ): () => void {
+ return subscribeKey(this.walletManager.state, 'address', (address) => {
+ callback(address);
+ });
+ }
+
+ onWalletSelected(
+ callback: (source: WalletSource | null) => void,
+ ): () => void {
+ return subscribeKey(this.walletManager.state, 'source', (source) => {
+ callback(source);
+ });
+ }
+}
diff --git a/packages/dapp-kit-ui/src/classes/custom-wallet-connect-modal.ts b/packages/dapp-kit-ui/src/classes/custom-wallet-connect-modal.ts
new file mode 100644
index 00000000..71a568ab
--- /dev/null
+++ b/packages/dapp-kit-ui/src/classes/custom-wallet-connect-modal.ts
@@ -0,0 +1,85 @@
+import { EventEmitter } from 'events';
+import type {
+ OpenOptions,
+ SubscribeModalState,
+ WCModal,
+} from '@vechain/dapp-kit';
+import { DAppKitLogger } from '@vechain/dapp-kit';
+import { dispatchCustomEvent, subscribeToCustomEvent } from '../utils';
+
+const MODAL_STATE_EVENT = 'vdk-modal-state-change';
+
+export class CustomWalletConnectModal implements WCModal {
+ private static instance: CustomWalletConnectModal | null = null;
+
+ private eventEmitter = new EventEmitter();
+
+ private constructor() {
+ subscribeToCustomEvent('vdk-close-wc-qrcode', () => {
+ this.updateModalState({ open: false });
+ });
+ subscribeToCustomEvent('vdk-open-wc-qrcode', () => {
+ this.updateModalState({ open: true });
+ });
+ }
+
+ static getInstance(): CustomWalletConnectModal {
+ if (!CustomWalletConnectModal.instance) {
+ CustomWalletConnectModal.instance = new CustomWalletConnectModal();
+ }
+
+ return CustomWalletConnectModal.instance;
+ }
+
+ /**
+ * WalletConnect
+ */
+ openModal(options: OpenOptions): Promise {
+ DAppKitLogger.debug('CustomWalletConnectModal', 'opening the wc modal');
+ dispatchCustomEvent('vdk-open-wc-qrcode', options);
+ return Promise.resolve();
+ }
+
+ closeModal(): void {
+ DAppKitLogger.debug('CustomWalletConnectModal', 'closing the modal');
+ dispatchCustomEvent('vdk-close-wc-qrcode');
+ }
+
+ askForConnectionCertificate(): void {
+ DAppKitLogger.debug(
+ 'CustomWalletConnectModal',
+ 'ask for connection certificate',
+ );
+ dispatchCustomEvent('vdk-close-wc-qrcode');
+ dispatchCustomEvent('vdk-request-connection-certificate');
+ }
+
+ onConnectionCertificateSigned(): void {
+ DAppKitLogger.debug(
+ 'CustomWalletConnectModal',
+ 'connection certificate signed',
+ );
+ dispatchCustomEvent('vdk-close-wallet-modal');
+ dispatchCustomEvent('vdk-close-wc-qrcode');
+ dispatchCustomEvent('vdk-close-connection-certificate-request');
+ }
+
+ subscribeModal(
+ callback: (newState: SubscribeModalState) => void,
+ ): () => void {
+ DAppKitLogger.debug(
+ 'CustomWalletConnectModal',
+ 'subscribing to modal state',
+ );
+
+ this.eventEmitter.on(MODAL_STATE_EVENT, callback);
+
+ return () => {
+ this.eventEmitter.off(MODAL_STATE_EVENT, callback);
+ };
+ }
+
+ private updateModalState(state: SubscribeModalState): void {
+ this.eventEmitter.emit(MODAL_STATE_EVENT, state);
+ }
+}
diff --git a/packages/dapp-kit-ui/src/classes/index.ts b/packages/dapp-kit-ui/src/classes/index.ts
new file mode 100644
index 00000000..74211e40
--- /dev/null
+++ b/packages/dapp-kit-ui/src/classes/index.ts
@@ -0,0 +1,2 @@
+export * from './connect-modal-manager';
+export * from './custom-wallet-connect-modal';
diff --git a/packages/dapp-kit-ui/src/client.ts b/packages/dapp-kit-ui/src/client.ts
index 30a5bc2f..c8fe5aa5 100644
--- a/packages/dapp-kit-ui/src/client.ts
+++ b/packages/dapp-kit-ui/src/client.ts
@@ -1,11 +1,11 @@
///
import type { DAppKitOptions, WalletManager } from '@vechain/dapp-kit';
import { DAppKit } from '@vechain/dapp-kit';
-import { CustomWalletConnectModal, DAppKitModal } from './modal';
+import { CustomWalletConnectModal, ConnectModalManager } from './classes';
import {
type CustomizedStyle,
dispatchCustomEvent,
- configureUI,
+ initModalsAndButtons,
} from './utils';
import type { SourceInfo, I18n, ThemeMode } from './constants';
@@ -32,15 +32,15 @@ export const DAppKitUI = {
CustomWalletConnectModal.getInstance();
}
dappKitOptions = options;
- if (!dappKit) dappKit = new DAppKit(options);
+ dappKit = new DAppKit(options);
- // init modal so on the first opening it doesn't have to create it
- DAppKitModal.getInstance(this.wallet, {
+ // init modal so that on the first opening it doesn't have to create it
+ ConnectModalManager.getInstance(this.wallet, {
modalParent: options.modalParent,
});
// configure bottons and modals options
- configureUI(options);
+ initModalsAndButtons(options);
dispatchCustomEvent('vdk-dapp-kit-configured');
initialized = true;
@@ -48,6 +48,12 @@ export const DAppKitUI = {
return dappKit;
},
+ configureButtonsAndModals(): void {
+ if (dappKitOptions) {
+ initModalsAndButtons(dappKitOptions);
+ }
+ },
+
get initialized(): boolean {
return initialized;
},
@@ -64,8 +70,8 @@ export const DAppKitUI = {
return this.get().wallet;
},
- get modal(): DAppKitModal {
- return DAppKitModal.getInstance(this.wallet, {
+ get modal(): ConnectModalManager {
+ return ConnectModalManager.getInstance(this.wallet, {
modalParent: dappKitOptions?.modalParent,
});
},
diff --git a/packages/dapp-kit-ui/src/components/buttons/button.ts b/packages/dapp-kit-ui/src/components/buttons/button.ts
index 1f78fd2e..b4c0b76c 100644
--- a/packages/dapp-kit-ui/src/components/buttons/button.ts
+++ b/packages/dapp-kit-ui/src/components/buttons/button.ts
@@ -1,6 +1,5 @@
import { html, LitElement, type TemplateResult } from 'lit';
import { customElement, property } from 'lit/decorators.js';
-import { type WalletManager } from '@vechain/dapp-kit';
import { subscribeKey } from 'valtio/vanilla/utils';
import { DAppKitUI } from '../../client';
import { defaultI18n, type I18n, type ThemeMode } from '../../constants';
@@ -13,6 +12,10 @@ export class Button extends LitElement {
if (DAppKitUI.initialized) {
this.address = DAppKitUI.wallet.state.address ?? '';
this.initAddressListener();
+ setTimeout(() => {
+ DAppKitUI.configureButtonsAndModals();
+ this.requestUpdate();
+ }, 0);
} else {
subscribeToCustomEvent('vdk-dapp-kit-configured', () => {
this.address = DAppKitUI.wallet.state.address ?? '';
@@ -28,10 +31,6 @@ export class Button extends LitElement {
});
}
- private get wallet(): WalletManager {
- return DAppKitUI.wallet;
- }
-
@property()
mode: ThemeMode = 'LIGHT';
diff --git a/packages/dapp-kit-ui/src/components/modals/address-modal.ts b/packages/dapp-kit-ui/src/components/modals/address-modal.ts
index afa3dc22..3bde7d03 100644
--- a/packages/dapp-kit-ui/src/components/modals/address-modal.ts
+++ b/packages/dapp-kit-ui/src/components/modals/address-modal.ts
@@ -1,7 +1,7 @@
import type { TemplateResult } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
-import type { I18n, SourceInfo } from '../../constants';
+import type { I18n } from '../../constants';
import { defaultI18n, Font } from '../../constants';
import { buttonStyle, iconButtonStyle } from '../../assets/styles';
import type { ThemeMode } from '../../constants/theme';
@@ -112,9 +112,6 @@ export class AddressModal extends LitElement {
@property({ type: String })
address = '';
- @property({ type: Function })
- onSourceClick?: (source?: SourceInfo) => void = undefined;
-
@property({ type: Function })
onDisconnectClick?: () => void = undefined;
diff --git a/packages/dapp-kit-ui/src/components/modals/connect-modal.ts b/packages/dapp-kit-ui/src/components/modals/connect-modal/connect-modal.ts
similarity index 55%
rename from packages/dapp-kit-ui/src/components/modals/connect-modal.ts
rename to packages/dapp-kit-ui/src/components/modals/connect-modal/connect-modal.ts
index afad496f..846eab5e 100644
--- a/packages/dapp-kit-ui/src/components/modals/connect-modal.ts
+++ b/packages/dapp-kit-ui/src/components/modals/connect-modal/connect-modal.ts
@@ -1,7 +1,7 @@
import type { TemplateResult } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
-import type { WalletManager } from '@vechain/dapp-kit';
+import { DAppKitLogger, type WalletManager } from '@vechain/dapp-kit';
import {
type I18n,
type SourceInfo,
@@ -9,16 +9,16 @@ import {
defaultI18n,
Font,
WalletSources,
-} from '../../constants';
+} from '../../../constants';
import {
DarkChevronLeftSvg,
DarkCloseSvg,
LightChevronLeftSvg,
LightCloseSvg,
-} from '../../assets/icons';
-import { isMobile, subscribeToCustomEvent, useTranslate } from '../../utils';
-import { DAppKitUI } from '../../client';
-import { iconButtonStyle } from '../../assets/styles';
+} from '../../../assets/icons';
+import { isMobile, subscribeToCustomEvent, useTranslate } from '../../../utils';
+import { DAppKitUI } from '../../../client';
+import { iconButtonStyle } from '../../../assets/styles';
@customElement('vdk-connect-modal')
export class ConnectModal extends LitElement {
@@ -47,28 +47,10 @@ export class ConnectModal extends LitElement {
`,
];
- @property({ type: Boolean })
- open = false;
-
- @property({ type: Boolean })
- openingVeWorld = false;
-
- @property()
- mode: ThemeMode = 'LIGHT';
-
- @property()
- i18n: I18n = defaultI18n;
-
- @property()
- language = 'en';
-
- @property()
- walletConnectQRcode?: string = undefined;
-
constructor() {
super();
- subscribeToCustomEvent('vdk-open-wc-modal', (options) => {
+ subscribeToCustomEvent('vdk-open-wc-qrcode', (options) => {
if (isMobile()) {
this.openingVeWorld = true;
window.open(
@@ -81,19 +63,25 @@ export class ConnectModal extends LitElement {
this.open = true;
this.walletConnectQRcode = options.uri;
});
-
- subscribeToCustomEvent('vdk-close-wc-modal', () => {
+ subscribeToCustomEvent('vdk-close-wc-qrcode', () => {
this.walletConnectQRcode = undefined;
this.openingVeWorld = false;
});
-
subscribeToCustomEvent('vdk-open-wallet-modal', () => {
this.open = true;
});
-
subscribeToCustomEvent('vdk-close-wallet-modal', () => {
this.open = false;
});
+ subscribeToCustomEvent('vdk-request-connection-certificate', () => {
+ this.requestForConnectionCertificate = true;
+ });
+ subscribeToCustomEvent(
+ 'vdk-close-connection-certificate-request',
+ () => {
+ this.requestForConnectionCertificate = false;
+ },
+ );
}
private get availableSources(): SourceInfo[] {
@@ -109,14 +97,22 @@ export class ConnectModal extends LitElement {
@property({ type: Function })
onSourceClick = (source?: SourceInfo): void => {
if (source) {
+ if (source.id !== 'wallet-connect') {
+ this.setWaitingForTheSignature(true);
+ this.requestForConnectionCertificate = true;
+ }
this.wallet.setSource(source.id);
this.wallet
.connect()
.then(() => {
this.requestUpdate();
})
- .finally(() => {
- DAppKitUI.modal.close();
+ .catch((err): void => {
+ DAppKitLogger.error(
+ 'Connection Attempt',
+ 'error trying to connect',
+ err,
+ );
});
}
};
@@ -124,19 +120,75 @@ export class ConnectModal extends LitElement {
@property({ type: Function })
onClose: () => void = () => nothing;
+ @property({ type: Boolean })
+ open = false;
+
+ @property({ type: Boolean })
+ openingVeWorld = false;
+
+ @property()
+ mode: ThemeMode = 'LIGHT';
+
+ @property()
+ i18n: I18n = defaultI18n;
+
+ @property()
+ language = 'en';
+
+ @property()
+ walletConnectQRcode?: string = undefined;
+
+ @property()
+ requestForConnectionCertificate = false;
+
+ @property()
+ waitingForTheSignature = false;
+
+ private setWaitingForTheSignature = (value: boolean): void => {
+ this.waitingForTheSignature = value;
+ };
+
+ private renderContent(): TemplateResult | TemplateResult[] {
+ if (this.requestForConnectionCertificate) {
+ return html``;
+ }
+ if (this.walletConnectQRcode) {
+ return html` `;
+ }
+ return this.availableSources.map(
+ (source) =>
+ html` `,
+ );
+ }
+
override render(): TemplateResult {
const translate = useTranslate(this.i18n, this.language);
return html`
-
-
+
-
-