From 75ebd204b6de47ef5e6a8eb14223efa3cbcc04eb Mon Sep 17 00:00:00 2001 From: Govard Barkhatov Date: Wed, 18 Dec 2024 16:12:59 +0200 Subject: [PATCH 1/6] connect story --- package-lock.json | 1 + src/components/TermsOfService/index.tsx | 2 +- .../WalletProvider/index.stories.tsx | 217 +++++++++++++++++- 3 files changed, 218 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4366598..1653ab4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2345,6 +2345,7 @@ "version": "0.22.1", "resolved": "https://registry.npmjs.org/@keystonehq/sdk/-/sdk-0.22.1.tgz", "integrity": "sha512-yBX2L3ieoZ1llj8Ocsiu+doDP+XtoI8oUPkv50oP3aBnzqM0IBsL46upWIVUWt5DucHAdGLGcVx9FxR9sQYZBw==", + "license": "ISC", "dependencies": { "@ngraveio/bc-ur": "^1.0.0", "@yudiel/react-qr-scanner": "2.0.0-beta.3", diff --git a/src/components/TermsOfService/index.tsx b/src/components/TermsOfService/index.tsx index 2fa382e..e0ab392 100644 --- a/src/components/TermsOfService/index.tsx +++ b/src/components/TermsOfService/index.tsx @@ -31,7 +31,7 @@ export function TermsOfService({ className, onClose, onSubmit }: Props) { return (
- Subtitle + Please read and accept the following terms diff --git a/src/components/WalletProvider/index.stories.tsx b/src/components/WalletProvider/index.stories.tsx index 3d69bca..07be98f 100644 --- a/src/components/WalletProvider/index.stories.tsx +++ b/src/components/WalletProvider/index.stories.tsx @@ -1,6 +1,9 @@ -import { Button, ScrollLocker } from "@babylonlabs-io/bbn-core-ui"; +import { Button, ScrollLocker, Text } from "@babylonlabs-io/bbn-core-ui"; import type { Meta, StoryObj } from "@storybook/react"; +import { useEffect, useState } from "react"; +import { useChainProviders } from "@/context/Chain.context"; +import { IBTCProvider } from "@/core/types"; import { useWidgetState } from "@/hooks/useWidgetState"; import { config } from "./constants"; @@ -34,3 +37,215 @@ export const Default: Story = { return ; }, }; + +export const WithConnectedData: Story = { + args: { + onError: console.log, + }, + decorators: [ + (Story) => ( + + + + + + ), + ], + render: () => { + const { open } = useWidgetState(); + const [walletData, setWalletData] = useState<{ + BTC?: { address: string; publicKeyHex: string }; + BBN?: { address: string; publicKeyHex: string }; + }>({}); + const connectors = useChainProviders(); + + useEffect(() => { + // Subscribe to connect events for both chains + const btcUnsub = connectors.BTC?.on("connect", async (wallet) => { + console.log("BTC Wallet connected", wallet); + if (wallet.account) { + const { address, publicKeyHex } = wallet.account; + if (address && publicKeyHex) { + setWalletData((prev) => ({ + ...prev, + BTC: { address, publicKeyHex }, + })); + } + } + }); + + const bbnUnsub = connectors.BBN?.on("connect", async (wallet) => { + console.log("BBN Wallet connected", wallet); + if (wallet.account) { + const { address, publicKeyHex } = wallet.account; + if (address && publicKeyHex) { + setWalletData((prev) => ({ + ...prev, + BBN: { address, publicKeyHex }, + })); + } + } + }); + + return () => { + btcUnsub?.(); + bbnUnsub?.(); + }; + }, [connectors]); + + return ( +
+ +
+ {walletData.BTC && ( +
+ + BTC Wallet + + Address: {walletData.BTC.address} + Public Key: {walletData.BTC.publicKeyHex} +
+ )} + + {walletData.BBN && ( +
+ + BBN Wallet + + Address: {walletData.BBN.address} + Public Key: {walletData.BBN.publicKeyHex} +
+ )} +
+
+ ); + }, +}; + +export const WithBTCSigningFeatures: Story = { + args: { + onError: console.log, + }, + decorators: [ + (Story) => ( + + + + + + ), + ], + render: () => { + const { open } = useWidgetState(); + const [messageToSign, setMessageToSign] = useState(""); + const [psbtToSign, setPsbtToSign] = useState(""); + const connectors = useChainProviders(); + const [walletData, setWalletData] = useState<{ + btcWallet?: IBTCProvider; + signedMessage?: string; + signedPsbt?: string; + }>({}); + + useEffect(() => { + const btcUnsub = connectors.BTC?.on("connect", async (wallet) => { + if (wallet.provider) { + setWalletData((prev) => ({ + ...prev, + btcWallet: wallet.provider as IBTCProvider, + })); + } + }); + + return () => { + btcUnsub?.(); + }; + }, [connectors]); + + const handleSignMessage = async () => { + if (!walletData.btcWallet || !messageToSign) return; + try { + const signature = await walletData.btcWallet.signMessage(messageToSign, "ecdsa"); + console.log("handleSignMessage:", signature); + setWalletData((prev) => ({ + ...prev, + signedMessage: signature, + })); + } catch (error) { + console.error("Failed to sign message:", error); + } + }; + + const handleSignPsbt = async () => { + if (!walletData.btcWallet || !psbtToSign) return; + try { + const signedPsbt = await walletData.btcWallet.signPsbt(psbtToSign); + console.log("handleSignPsbt:", signedPsbt); + setWalletData((prev) => ({ + ...prev, + signedPsbt, + })); + } catch (error) { + console.error("Failed to sign PSBT:", error); + } + }; + + return ( +
+ +
+ {walletData.btcWallet && ( +
+
+ + Sign Message + + setMessageToSign(e.target.value)} + placeholder="Enter message to sign" + className="b-mb-2 b-w-full b-rounded b-border b-p-2" + /> + + {walletData.signedMessage && ( +
+ + Signed Message: {walletData.signedMessage} + + +
+ )} +
+ +
+ + Sign PSBT + + setPsbtToSign(e.target.value)} + placeholder="Enter PSBT hex" + className="b-mb-2 b-w-full b-rounded b-border b-p-2" + /> + + {walletData.signedPsbt && ( +
+ + Signed PSBT: {walletData.signedPsbt} + + +
+ )} +
+
+ )} +
+
+ ); + }, +}; From 42aafc488e9bb27b722ee741b9ff9a85a9d42b61 Mon Sep 17 00:00:00 2001 From: Govard Barkhatov Date: Wed, 18 Dec 2024 22:32:19 +0200 Subject: [PATCH 2/6] extract transaction --- .../WalletProvider/index.stories.tsx | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/components/WalletProvider/index.stories.tsx b/src/components/WalletProvider/index.stories.tsx index 07be98f..fa627dc 100644 --- a/src/components/WalletProvider/index.stories.tsx +++ b/src/components/WalletProvider/index.stories.tsx @@ -1,5 +1,6 @@ import { Button, ScrollLocker, Text } from "@babylonlabs-io/bbn-core-ui"; import type { Meta, StoryObj } from "@storybook/react"; +import { Psbt } from "bitcoinjs-lib"; import { useEffect, useState } from "react"; import { useChainProviders } from "@/context/Chain.context"; @@ -137,14 +138,15 @@ export const WithBTCSigningFeatures: Story = { ], render: () => { const { open } = useWidgetState(); - const [messageToSign, setMessageToSign] = useState(""); - const [psbtToSign, setPsbtToSign] = useState(""); + const [messageToSign, setMessageToSign] = useState(""); + const [psbtToSign, setPsbtToSign] = useState(""); const connectors = useChainProviders(); const [walletData, setWalletData] = useState<{ btcWallet?: IBTCProvider; signedMessage?: string; signedPsbt?: string; }>({}); + const [transaction, setTransaction] = useState(""); useEffect(() => { const btcUnsub = connectors.BTC?.on("connect", async (wallet) => { @@ -236,11 +238,37 @@ export const WithBTCSigningFeatures: Story = { Signed PSBT: {walletData.signedPsbt} -
)} + {walletData.signedPsbt && ( +
+ + Transaction: {transaction} + + +
+ )} )} From 833a0d08654a065101a83c9ea8e62e0bb426130d Mon Sep 17 00:00:00 2001 From: Govard Barkhatov Date: Thu, 19 Dec 2024 18:48:21 +0200 Subject: [PATCH 3/6] Update src/components/WalletProvider/index.stories.tsx Co-authored-by: David Totrashvili <8580261+totraev@users.noreply.github.com> --- .../WalletProvider/index.stories.tsx | 71 ++++--------------- 1 file changed, 12 insertions(+), 59 deletions(-) diff --git a/src/components/WalletProvider/index.stories.tsx b/src/components/WalletProvider/index.stories.tsx index fa627dc..55ef18e 100644 --- a/src/components/WalletProvider/index.stories.tsx +++ b/src/components/WalletProvider/index.stories.tsx @@ -38,7 +38,6 @@ export const Default: Story = { return ; }, }; - export const WithConnectedData: Story = { args: { onError: console.log, @@ -53,69 +52,23 @@ export const WithConnectedData: Story = { ), ], render: () => { - const { open } = useWidgetState(); - const [walletData, setWalletData] = useState<{ - BTC?: { address: string; publicKeyHex: string }; - BBN?: { address: string; publicKeyHex: string }; - }>({}); - const connectors = useChainProviders(); - - useEffect(() => { - // Subscribe to connect events for both chains - const btcUnsub = connectors.BTC?.on("connect", async (wallet) => { - console.log("BTC Wallet connected", wallet); - if (wallet.account) { - const { address, publicKeyHex } = wallet.account; - if (address && publicKeyHex) { - setWalletData((prev) => ({ - ...prev, - BTC: { address, publicKeyHex }, - })); - } - } - }); - - const bbnUnsub = connectors.BBN?.on("connect", async (wallet) => { - console.log("BBN Wallet connected", wallet); - if (wallet.account) { - const { address, publicKeyHex } = wallet.account; - if (address && publicKeyHex) { - setWalletData((prev) => ({ - ...prev, - BBN: { address, publicKeyHex }, - })); - } - } - }); - - return () => { - btcUnsub?.(); - bbnUnsub?.(); - }; - }, [connectors]); + const { open, selectedWallets } = useWidgetState(); return (
- {walletData.BTC && ( -
- - BTC Wallet - - Address: {walletData.BTC.address} - Public Key: {walletData.BTC.publicKeyHex} -
- )} - - {walletData.BBN && ( -
- - BBN Wallet - - Address: {walletData.BBN.address} - Public Key: {walletData.BBN.publicKeyHex} -
+ {Object.entries(selectedWallets).map( + ([chainName, wallet]) => + wallet?.account && ( +
+ + {chainName} Wallet + + Address: {wallet.account.address} + Public Key: {wallet.account.publicKeyHex} +
+ ), )}
From 4ff0768733cf8798854c6a6265d314bffc72b6da Mon Sep 17 00:00:00 2001 From: Govard Barkhatov Date: Thu, 19 Dec 2024 18:48:35 +0200 Subject: [PATCH 4/6] Update src/components/WalletProvider/index.stories.tsx Co-authored-by: David Totrashvili <8580261+totraev@users.noreply.github.com> --- .../WalletProvider/index.stories.tsx | 113 ++++++++---------- 1 file changed, 47 insertions(+), 66 deletions(-) diff --git a/src/components/WalletProvider/index.stories.tsx b/src/components/WalletProvider/index.stories.tsx index 55ef18e..d0708c1 100644 --- a/src/components/WalletProvider/index.stories.tsx +++ b/src/components/WalletProvider/index.stories.tsx @@ -90,55 +90,33 @@ export const WithBTCSigningFeatures: Story = { ), ], render: () => { - const { open } = useWidgetState(); + const { open, selectedWallets } = useWidgetState(); const [messageToSign, setMessageToSign] = useState(""); const [psbtToSign, setPsbtToSign] = useState(""); - const connectors = useChainProviders(); - const [walletData, setWalletData] = useState<{ - btcWallet?: IBTCProvider; - signedMessage?: string; - signedPsbt?: string; - }>({}); + const [signedMessage, setSignedMessage] = useState(""); + const [signedPsbt, setSignedPsbt] = useState(""); const [transaction, setTransaction] = useState(""); - useEffect(() => { - const btcUnsub = connectors.BTC?.on("connect", async (wallet) => { - if (wallet.provider) { - setWalletData((prev) => ({ - ...prev, - btcWallet: wallet.provider as IBTCProvider, - })); - } - }); - - return () => { - btcUnsub?.(); - }; - }, [connectors]); + const btcProvider = selectedWallets.BTC?.provider as IBTCProvider | undefined; const handleSignMessage = async () => { - if (!walletData.btcWallet || !messageToSign) return; + if (!btcProvider || !messageToSign) return; + try { - const signature = await walletData.btcWallet.signMessage(messageToSign, "ecdsa"); + const signature = await btcProvider.signMessage(messageToSign, "ecdsa"); console.log("handleSignMessage:", signature); - setWalletData((prev) => ({ - ...prev, - signedMessage: signature, - })); + setSignedMessage(signature); } catch (error) { console.error("Failed to sign message:", error); } }; const handleSignPsbt = async () => { - if (!walletData.btcWallet || !psbtToSign) return; + if (!btcProvider || !psbtToSign) return; try { - const signedPsbt = await walletData.btcWallet.signPsbt(psbtToSign); + const signedPsbt = await btcProvider.signPsbt(psbtToSign); console.log("handleSignPsbt:", signedPsbt); - setWalletData((prev) => ({ - ...prev, - signedPsbt, - })); + setSignedPsbt(signedPsbt); } catch (error) { console.error("Failed to sign PSBT:", error); } @@ -146,71 +124,74 @@ export const WithBTCSigningFeatures: Story = { return (
- + +
- {walletData.btcWallet && ( + {btcProvider && (
- - Sign Message - - setMessageToSign(e.target.value)} - placeholder="Enter message to sign" - className="b-mb-2 b-w-full b-rounded b-border b-p-2" - /> + + setMessageToSign(e.target.value)} + placeholder="Enter message to sign" + /> + + - {walletData.signedMessage && ( + + {signedMessage && (
- Signed Message: {walletData.signedMessage} + Signed Message: {signedMessage} - +
)}
- - Sign PSBT - - setPsbtToSign(e.target.value)} - placeholder="Enter PSBT hex" - className="b-mb-2 b-w-full b-rounded b-border b-p-2" - /> + + setPsbtToSign(e.target.value)} + placeholder="Enter PSBT hex" + /> + + - {walletData.signedPsbt && ( + + {signedPsbt && (
- Signed PSBT: {walletData.signedPsbt} + Signed PSBT: {signedPsbt}
)} - {walletData.signedPsbt && ( + + {signedPsbt && (
Transaction: {transaction}