Skip to content

Commit

Permalink
feat: add Xverse to Connect Wallet component
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev committed Jul 29, 2024
1 parent a428313 commit a102414
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 71 deletions.
37 changes: 33 additions & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,43 @@
"use client";

import { ConnectButton } from "@rainbow-me/rainbowkit";
import { ConnectBitcoin } from "@/index";
import {
Swap,
useEthersSigner,
useZetaChainClient,
ConnectBitcoin,
useBitcoinWallet,
} from "@/index";
import { useAccount, useChainId, useWalletClient } from "wagmi";

const contract = "0xb459F14260D1dc6484CE56EB0826be317171e91F"; // universal swap contract

const Page = () => {
const account = useAccount();
const chainId = useChainId();
const { data: walletClient } = useWalletClient({ chainId });
const signer = useEthersSigner({ walletClient });
const client = useZetaChainClient({ network: "testnet", signer });
const { address: bitcoinAddress } = useBitcoinWallet();

return (
<div>
<ConnectBitcoin />
<ConnectButton />
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">
{client && (
<Swap
contract={contract}
client={client}
account={account}
bitcoin={bitcoinAddress}
/>
)}
</div>
</div>
</div>
);
};
Expand Down
31 changes: 31 additions & 0 deletions src/components/ConnectBitcoin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ import Image, { StaticImageData } from "next/image";
import okxIcon from "./okx.jpeg";
import xdefiIcon from "./xdefi.jpeg";
import unisatIcon from "./unisat.jpeg";
import xverseIcon from "./xverse.jpeg";
import {
Params,
Requests,
RpcResult,
SupportedWallet,
defaultAdapters,
getSupportedWallets,
SatsConnectAdapter,
setDefaultProvider,
getDefaultProvider,
removeDefaultProvider,
RpcErrorCode,
AddressPurpose,
BaseAdapter,
} from "@sats-connect/core";

const formatAddress = (str: string): string => {
if (str.length <= 10) {
Expand Down Expand Up @@ -130,6 +146,14 @@ const Details = React.memo(({ address, disconnect }: any) => {
});

const Connect = React.memo(({ connectWallet, loading }: any) => {
const connectXverse = async () => {
const adapter = new BaseAdapter("XverseProviders.BitcoinProvider");
const accounts = await adapter.request("getAccounts", {
purposes: [AddressPurpose.Stacks, AddressPurpose.Payment],
});
console.log(accounts);
};

return (
<Dialog>
<DialogTrigger asChild>
Expand Down Expand Up @@ -166,6 +190,13 @@ const Connect = React.memo(({ connectWallet, loading }: any) => {
connectWallet={connectWallet}
loading={loading}
/>
<WalletButton
walletType="xverse"
icon={xverseIcon}
label="Xverse"
connectWallet={connectWallet}
loading={loading}
/>
</div>
</DialogContent>
</Dialog>
Expand Down
Binary file added src/components/ConnectBitcoin/xverse.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 21 additions & 25 deletions src/providers/BitcoinWalletProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import React, { createContext, useContext, useState, ReactNode } from "react";
import unisatWallet from "./unisat";
import okxWallet from "./okx";
import xdefiWallet from "./xdefi";
import xverseWallet from "./xverse";

export const walletTypes = {
unisat: unisatWallet,
okx: okxWallet,
xdefi: xdefiWallet,
xverse: xverseWallet,
};

export type WalletType = keyof typeof walletTypes;

interface WalletContextProps {
address: string | null;
publicKey: string | null;
loading: { isLoading: boolean; walletType: WalletType | null };
connectedWalletType: WalletType | null;
connectWallet: (walletType: WalletType) => void;
Expand All @@ -34,6 +37,7 @@ export const BitcoinWalletProvider = ({
children: ReactNode;
}) => {
const [address, setAddress] = useState<string | null>(null);
const [publicKey, setPublicKey] = useState<string | null>(null);
const [loading, setLoading] = useState<{
isLoading: boolean;
walletType: WalletType | null;
Expand All @@ -44,23 +48,19 @@ export const BitcoinWalletProvider = ({
const connectWallet = async (walletType: WalletType) => {
setAddress(null);
const walletConfig = walletTypes[walletType];
const wallet = (window as any)[walletConfig.name];
if (wallet) {
setLoading({ isLoading: true, walletType });
try {
const address = await walletConfig.getAddress(wallet);
setAddress(address);
setConnectedWalletType(walletType);
} catch (error) {
console.error(`Connection to ${walletConfig.label} failed:`, error);
setLoading({ isLoading: false, walletType: null });
return;
}
setLoading({ isLoading: false, walletType: null });
} else {
console.error("Unsupported wallet type");

setLoading({ isLoading: true, walletType });
try {
const { address, publicKey } = await walletConfig.getAddress();
setAddress(address);
setPublicKey(publicKey);
setConnectedWalletType(walletType);
} catch (error) {
console.error(`Connection to ${walletConfig.label} failed:`, error);
setLoading({ isLoading: false, walletType: null });
return;
}
setLoading({ isLoading: false, walletType: null });
};

const disconnect = () => {
Expand All @@ -79,23 +79,19 @@ export const BitcoinWalletProvider = ({
}

const walletConfig = walletTypes[connectedWalletType];
const wallet = (window as any)[walletConfig.name];
if (wallet) {
try {
const txHash = await walletConfig.sendTransaction(wallet, params);
console.log(`Broadcasted a transaction: ${txHash}`);
} catch (error) {
console.error(`Transaction with ${walletConfig.label} failed:`, error);
}
} else {
console.error("Unsupported wallet type");
try {
const txHash = await walletConfig.sendTransaction(params);
console.log(`Broadcasted a transaction: ${txHash}`);
} catch (error) {
console.error(`Transaction with ${walletConfig.label} failed:`, error);
}
};

return (
<BitcoinWalletContext.Provider
value={{
address,
publicKey,
loading,
connectedWalletType,
connectWallet,
Expand Down
28 changes: 14 additions & 14 deletions src/providers/BitcoinWalletProvider/okx.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
export default {
label: "OKX Wallet",
name: "okxwallet",
getAddress: async (wallet: any) => {
return (await wallet.bitcoinTestnet.connect()).address;
getAddress: async () => {
const wallet = (window as any).okxwallet;
const address = (await wallet.bitcoinTestnet.connect()).address;
return { address, publicKey: null };
},
sendTransaction: async (
wallet: any,
{
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}
) => {
sendTransaction: async ({
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}) => {
const wallet = (window as any).okxwallet;
const account = await wallet?.bitcoinTestnet?.connect();
if (!account) throw new Error("No account found");
const txHash = await wallet.bitcoinTestnet.send({
Expand Down
28 changes: 14 additions & 14 deletions src/providers/BitcoinWalletProvider/unisat.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
export default {
label: "Unisat Wallet",
name: "unisat",
getAddress: async (wallet: any) => {
return (await wallet.requestAccounts())[0];
getAddress: async () => {
const wallet = (window as any).unisat;
const address = (await wallet.requestAccounts())[0];
return { address, publicKey: null };
},
sendTransaction: async (
wallet: any,
{
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}
) => {
sendTransaction: async ({
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}) => {
const wallet = (window as any).unisat;
await wallet.requestAccounts();
const memos = memo && [memo.toLowerCase()];
const tx = await wallet.sendBitcoin(to, value * 1e8, { memos });
Expand Down
28 changes: 14 additions & 14 deletions src/providers/BitcoinWalletProvider/xdefi.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
export default {
label: "XDEFI Wallet",
name: "xfi",
getAddress: async (wallet: any) => {
getAddress: async () => {
const wallet = (window as any).xfi;
wallet.bitcoin.changeNetwork("testnet");
return (await wallet?.bitcoin?.getAccounts())[0];
const address = (await wallet?.bitcoin?.getAccounts())[0];
return { address, publicKey: null };
},
sendTransaction: async (
wallet: any,
{
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}
) => {
sendTransaction: async ({
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}) => {
const wallet = (window as any).unisat;
wallet.bitcoin.changeNetwork("testnet");
const account = (await wallet?.bitcoin?.getAccounts())?.[0];
if (!account) throw new Error("No account found");
Expand Down
43 changes: 43 additions & 0 deletions src/providers/BitcoinWalletProvider/xverse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { AddressPurpose, BaseAdapter } from "@sats-connect/core";
import { createTransaction, signPsbt } from "./utils";

export default {
label: "Xverse Wallet",
name: "xverse",
getAddress: async () => {
const adapter = new BaseAdapter("XverseProviders.BitcoinProvider");
const accounts: any = await adapter.request("getAccounts", {
purposes: [AddressPurpose.Payment, AddressPurpose.Payment],
});
console.log(accounts);
return {
address: accounts.result[0].address,
publicKey: accounts.result[0].publicKey,
};
},
sendTransaction: async ({
to,
value,
memo,
}: {
to: string;
value: number;
memo?: string;
}) => {
const adapter = new BaseAdapter("XverseProviders.BitcoinProvider");
const accounts: any = await adapter.request("getAccounts", {
purposes: [AddressPurpose.Payment, AddressPurpose.Payment],
});
const address = accounts.result[0].address;
const publicKey = accounts.result[0].publicKey;

const result = await createTransaction(publicKey, address, {
memo,
amount: value * 1e8,
to,
});

const res = await signPsbt(result.psbtB64, result.utxoCnt, address);
console.log(res);
},
};
Loading

0 comments on commit a102414

Please sign in to comment.