https://github.com/fran-dv/bch-connect-monorepo
Seamlessly connect Bitcoin Cash wallets to your react dApp.
https://github.com/fran-dv/bch-connect-monorepo
bitcoincash dapp library react typescript web3
Last synced: 3 months ago
JSON representation
Seamlessly connect Bitcoin Cash wallets to your react dApp.
- Host: GitHub
- URL: https://github.com/fran-dv/bch-connect-monorepo
- Owner: fran-dv
- License: mit
- Created: 2025-09-25T17:46:50.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2026-01-30T17:47:35.000Z (5 months ago)
- Last Synced: 2026-04-08T20:55:10.284Z (3 months ago)
- Topics: bitcoincash, dapp, library, react, typescript, web3
- Language: TypeScript
- Homepage: https://bch-connect-example.netlify.app/
- Size: 1.39 MB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# BCH Connect
[](https://www.npmjs.com/package/bch-connect)
[](./LICENSE)
A React library to seamlessly integrate Bitcoin Cash wallet connections in your dApps. π
**_π§ Actively working on online docs..._**
## Table of contents
- [β‘ Getting started](#getting-started)
- [π‘ Example](#example)
- [π§© API reference](#api-reference)
- [π§βπ» Local development](#local-development)
- [π€ Contribute](#contribute)
### Quick Start
The easiest way to build a BCH dApp is using our scaffolding tool. It sets up **React + Vite** or **Next.js** with TypeScript and BCH Connect pre-configured and ready to use.
Just run:
```bash
bun create bch-dapp
# Or use your preferred package manager.
```
### Manual installation
If you already have a project and want to add **bch-connect**, follow these steps:
**1. Install the package:**
```bash
npm install bch-connect
```
Or replace `npm` with your preferred package manager.
**2. Set up your configuration**
You'll need a Reown project ID. Get it from [Reown dashboard](https://dashboard.reown.com). Then, in your `main.tsx`, `App`, or in a specific `config.ts` file:
```tsx
import { createConfig } from "bch-connect";
export const config = createConfig({
projectId: "your-reown-project-id", // Get it from https://dashboard.reown.com
network: "testnet", // or "mainnet"
metadata: {
name: "Your dApp name",
description: "Your dApp description",
url: "https://your-dapp.com",
icons: ["https://placehold.co/600x400?text=YourDApp"],
},
debug: true,
});
```
**3. Wrap your app with the provider**
In your `main.tsx` or `App`:
```tsx
// App.tsx
import { config } from "./your-config-file";
import { BCHConnectProvider } from "bch-connect";
function App() {
return (
);
}
```
**4. Start using it!**
```tsx
import { useWallet } from "bch-connect";
const ConnectButton = () => {
const { connect } = useWallet();
return Connect Wallet;
};
```
Visit the example [**live demo here**](https://bch-connect-example.netlify.app/).
Below are some code snippets from the example app. To view the full code or run it locally, check the [simple-transaction example](examples/simple-transaction/) folder in this repository.
### Connect button:
```tsx
// other imports...
import { useWallet } from "bch-connect";
// styles and UI code are omitted here
export const ConnectButton: React.FC<
ButtonHTMLAttributes
> = (props: ButtonHTMLAttributes) => {
const { connect, isConnected, address, disconnect } = useWallet();
const handleWalletConnect = () => {
if (isConnected) return;
connect();
};
const handleWalletDisconnect = () => {
disconnect();
};
return (
{isConnected && address ? (
) : (
"Connect Wallet"
)}
{isConnected && (
)}
);
};
export default ConnectButton;
```
### Sending a transaction using bch-connect and cashscript SDK, with recipient and amount entered through a form:
```tsx
// other imports...
import { useSignTransaction, useWallet } from "bch-connect";
export const Example: React.FC = () => {
// bch-connect hooks
const { address, tokenAddress, isConnected } = useWallet();
const { signTransaction } = useSignTransaction();
// -----------------
// other hooks from the example app
const { showSuccess, showError, showMessage } = useUserMessages();
const { provider } = useNetworkProviderStore(); // Cashscript's NetworkProvider
const { balance, error: balanceError } = useBalance({ address });
const [isLoading, setIsLoading] = useState(false);
const proposeTransactionToWallet = async (values: TransferFormValues) => {
if (!isConnected || !address || !provider) return;
setIsLoading(true);
// helper function to create a transaction object
const wcTransactionObj = await getSimpleTransaction({
provider,
sender: address,
amount: values.satoshis,
recipient: values.recipient,
});
showMessage("Please sign the transaction in your wallet...");
// Request signature of the generated transaction to the wallet
try {
const response = await signTransaction({ txRequest: wcTransactionObj });
// Defensive checking for malformed response received from wallet
if (!response) {
showMessage(
"Transaction status couldnβt be tracked. Please check your wallet to see if it was sent or rejected.",
);
return;
}
showSuccess(
`Tx signed successfully. Hash: ${response.signedTransactionHash}`,
);
} catch (error) {
const errorMsg = (error as Error).message;
showError("Failed to sign transaction: " + errorMsg);
} finally {
setIsLoading(false);
}
};
// Below, TransferCard has the form, which call proposeTransactionToWallet on submit
// and WalletInfoCard just shows addresses and balance
return (
);
};
export default Example;
```
### `createConfig(options: Configuration): CreatedConfig`
Creates the configuration object required by `BCHConnectProvider`, applying defaults for you.
**Parameters:**
- `options`: `Configuration` object.
```ts
export interface Configuration {
projectId: string;
network: NETWORK_INDEX | keyof typeof NETWORK_INDEX; // "mainnet" | "testnet" | "regtest"
metadata: {
name: string;
description: string;
url: string;
icons: string[];
};
sessionType?: SessionType;
modal?: Modal | ModalFactory; // defaults to bchConnectModal()
supportLegacyClient?: boolean; // defaults to true. It ensures working with required namespaces
debug?: boolean; // defaults to false
}
```
**Returns:**
- `CreatedConfig` β branded configuration to pass to the provider.
### `bchConnectModal(config?: BCHConnectModalConfig): Modal`
[bch-connect-modal](/packages/bch-connect-modal/) factory function. Default modal adapter used when you donβt pass a `modal` to `createConfig`. Wraps the `bch-connect-modal` package and accepts the same configuration (with `sessionType` defaulting to `"Wallet Connect V2"`).
**Parameters:**
- `config` (optional): `BCHConnectModalConfig`
```ts
interface BCHConnectModalConfig {
sessionType: SessionType; // "Wallet Connect V2"
wallets?: {
id: string;
name: string;
iconUrl: string;
links: {
fallback: string;
native?: string;
universal?: string;
web?: string;
};
}[]; // optional curated wallet list
theme?: "light" | "dark" | "system"; // modal theme
}
```
**Returns:**
- `Modal` β object with `open({ uri })` and `close()` methods used internally by BCH Connect.
### `reownModal(options): ModalFactory`
Factory to use Reown AppKitβs modal. Pass the returned function as `modal` in `createConfig`. Accepts all `createAppKit` options except `projectId`, `metadata`, `manualWCControl`, and `networks` (BCH Connect injects those for you).
**Parameters:**
- `options`: `Omit`
**Returns:**
- `ModalFactory` β async factory that BCH Connect will call with `{ projectId, network, sessionType }` to build the modal.
### ``
Provides the React context for BCH Connect, enabling wallet connections throughout your app.
This should wrap your root component (e.g. `App.tsx`).
**Props:**
- `config`: `CreatedConfig` β the object returned by [`createConfig`](#createconfigoptions-configuration-createdconfig).
- `children`: `React.ReactNode` β your application components.
### `useWallet()`
React hook to access the current wallet connection state and perform connect/disconnect actions.
Must be used within a [``](#bchconnectprovider-configconfig) context.
**Returns:**
- `address` β the currently connected wallet address. It is automatically refetched when an `addressesChanged` event is emitted by the wallet.
- `tokenAddress` β the [CashTokens](https://cashtokens.org/) aware address of the wallet, derived from `address`. It is automatically refetched when `address` changes.
- `session` β the active WalletConnect session (`SessionTypes.Struct`) or `null` when disconnected.
- `isConnected` β boolean indicating whether a wallet is currently connected.
- `connect()` β initiates a wallet connection.
- `disconnect()` β disconnects the current wallet session.
- `refetchAddresses()` β programmatically refetches `address`, updating both `address` and `tokenAddress` states.
- `areAddressesLoading` β boolean indicating whether the addresses are currently being loaded.
- `addressError` β error object if an error occurred while fetching the address.
- `tokenAddressError` β error object if an error occurred while converting address to token address.
- `connectError` β error object if an error occurred while connecting to a wallet.
- `disconnectError` β error object if an error occurred while disconnecting from a wallet.
- `isError` β boolean indicating whether an error occurred.
```ts
interface UseWalletReturnType {
address: string | null;
tokenAddress: string | null;
areAddressesLoading: boolean;
addressError: Error | null;
tokenAddressError: Error | null;
isConnected: boolean;
session: SessionTypes.Struct | null;
connectError: Error | null;
disconnectError: Error | null;
isError: boolean;
connect: () => Promise;
disconnect: () => Promise;
refetchAddresses: () => Promise;
}
```
### `useSignTransaction()`
React hook to sign Bitcoin Cash transactions with the connected wallet.
It works within [``](#bchconnectprovider-configconfig) context and when a wallet session is active.
**Returns:**
```ts
interface UseSignTransactionReturnType {
signTransaction: (
options: SignTransactionOpts,
) => Promise;
}
interface SignTransactionOpts {
txRequest: WcSignTransactionRequest;
requestExpirySeconds?: number; // defaults to 300 seconds
}
```
`WcSignTransactionRequest` and `WcSignTransactionResponse` are interfaces from [`@bch-wc2/interfaces`](https://github.com/mainnet-pat/bch-wc2) package, which are also re-exported by `bch-connect` for convenience.
**`signTransaction` parameters:**
- `options.txRequest`: `WcSignTransactionRequest`
- `options.requestExpirySeconds`: optional expiration for the WalletConnect request in seconds (defaults to 300).
```ts
interface WcSignTransactionRequest {
transaction: Transaction | string;
sourceOutputs: WcSourceOutput[];
broadcast?: boolean;
userPrompt?: string;
}
```
Youβll commonly pass a `WcTransactionObject` from `cashscript` as the parameter to this function, which is fully compatible. This is shown in the [simple-transaction example](/examples/simple-transaction)
**`signTransaction` returns:**
- `Promise` β resolves with the signed transaction response. Returns `null` when the wallet returns an invalid empty-object response, allowing you to show a neutral βstatus unknownβ message. Throws if the WalletConnect client/session is missing or the wallet rejects/returns an error.
It should be used within a try / catch block.
```ts
interface WcSignTransactionResponse {
signedTransaction: string;
signedTransactionHash: string;
}
```
### `useSignMessage()`
React hook to sign arbitrary messages with the connected wallet.
It works when your app is wrapped with `` and when a wallet session is active.
**Returns:**
```ts
interface UseSignMessageReturnType {
signMessage: (
options: WcSignMessageRequest,
) => Promise;
}
```
`WcSignMessageRequest` and `WcSignMessageResponse` are interfaces from [`@bch-wc2/interfaces`](https://github.com/mainnet-pat/bch-wc2), which are also re-exported by `bch-connect` for convenience.
**`signMessage` parameters:**
- `options`: `WcSignMessageRequest`
```ts
interface WcSignMessageRequest {
message: string;
userPrompt?: string;
}
```
**`signMessage` returns:**
- `Promise` β resolves with the message signature as a string. Throws if the WalletConnect client/session is missing or the wallet rejects/returns an error.
It should be used within a try / catch block.
```ts
type WcSignMessageResponse = string;
```
## π§βπ» Local Development (for contributors)
This is a Bun-powered monorepo (`packages/*`, `examples/*`, `docs`). After cloning, install everything once from the root:
```bash
git clone https://github.com/fran-dv/bch-connect-monorepo.git
cd bch-connect-monorepo
bun install
```
### Library (`packages/bch-connect`)
Development (tsup watch writes to `dist/`):
```bash
cd packages/bch-connect
bun dev
```
Tests and tooling:
```bash
bun test # or: bun test:coverage
bun run lint
bun run format
```
### Modal (`packages/bch-connect-modal`)
Playground (watch + serve `src/index.html` with the built global bundle):
```bash
cd packages/bch-connect-modal
bun run dev:playground # serves at http://localhost:4173
```
The playground needs manual reload on the browser to see changes.
Bundle without serving:
```bash
bun dev # watch build
bun run build # without minification
bun run build:prod # with minification
```
Tests:
```bash
bun test
bun test:coverage
```
### Example app (`examples/simple-transaction`)
Run the demo:
```bash
cd examples/simple-transaction
bun dev
```
Build and preview:
```bash
bun run build
bun run preview
```
### Docs site (`docs`)
Preview locally (Next.js):
```bash
cd docs
bun run dev
```
Production build and type/MDX checks:
```bash
bun run build
bun run types:check
```
This project is open source and contributions are more than welcome!
Licensed under MIT β feel free to copy, modify, and use the code in your own projects.
---
Built with π by [fran-dv](https://github.com/fran-dv)