otx-btc-wallet-core
v0.1.0
Published
Core state management and types for otx-btc-wallet
Readme
otx-btc-wallet-core
Core state management, types, and configuration for the otx-btc-wallet library. This package provides the foundation that connectors and React hooks build on.
Installation
pnpm add otx-btc-wallet-coreOverview
This package includes:
createConfig()- Configuration factory that initializes the store and connectors- Zustand Store - Reactive state management with persistence and auto-reconnect
- TypeScript Types - Full type definitions for connectors, accounts, networks, and PSBTs
- PSBT Utilities - Hex/Base64 conversion, validation, and sighash helpers
Usage
Create Config
import { createConfig } from 'otx-btc-wallet-core';
import { UnisatConnector, XverseConnector } from 'otx-btc-wallet-connectors';
const config = createConfig({
connectors: [
new UnisatConnector(),
new XverseConnector(),
],
});Config Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| connectors | BitcoinConnector[] | (required) | Wallet connectors to register |
| autoConnect | boolean | true | Auto-reconnect to last used wallet on page load |
| storage | Storage | localStorage | Storage backend for persistence |
| storageKey | string | 'optimex-btc-wallet.store' | Key prefix for persisted state |
Validation:
- At least one connector must be provided
- Duplicate connector IDs will throw an error
Access the Store Directly
The config object contains a Zustand store you can use outside of React:
const config = createConfig({ /* ... */ });
// Read current state
const { status, account, connector, network } = config.store.getState();
// Subscribe to changes
const unsubscribe = config.store.subscribe(
(state) => state.account,
(account) => console.log('Account changed:', account),
);
// Perform actions
await config.store.getState().connect(connector);
await config.store.getState().disconnect();Types
BitcoinNetwork
type BitcoinNetwork = 'mainnet' | 'testnet' | 'testnet4' | 'signet';AddressType
type AddressType = 'legacy' | 'nested-segwit' | 'segwit' | 'taproot';WalletAccount
type WalletAccount = {
address: string;
publicKey: string;
type: AddressType;
};MultiAddressAccount
Used by wallets like Xverse that provide separate payment and ordinals addresses.
type MultiAddressAccount = {
payment: WalletAccount;
ordinals: WalletAccount;
};BitcoinConnector
The interface all wallet connectors must implement.
interface BitcoinConnector {
readonly id: string;
readonly name: string;
readonly icon: string;
ready: boolean;
connect(network?: BitcoinNetwork): Promise<WalletAccount>;
disconnect(): Promise<void>;
getAccounts(): Promise<WalletAccount[]>;
signMessage(message: string): Promise<string>;
signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;
signPsbts?(psbtHexs: string[], options?: SignPsbtOptions): Promise<string[]>;
sendTransaction(to: string, satoshis: number): Promise<string>;
getNetwork(): Promise<BitcoinNetwork>;
switchNetwork?(network: BitcoinNetwork): Promise<void>;
onAccountsChanged(callback: (accounts: WalletAccount[]) => void): () => void;
onNetworkChanged(callback: (network: BitcoinNetwork) => void): () => void;
}SignPsbtOptions
type SignPsbtOptions = {
autoFinalize?: boolean; // Auto-finalize inputs after signing
broadcast?: boolean; // Broadcast the transaction after signing
toSignInputs?: SignInput[]; // Specify which inputs to sign
};SignInput
type SignInput = {
index: number; // Input index
address?: string; // Address owning this input
publicKey?: string; // Public key for this input
sighashTypes?: number[]; // Sighash types to use
disableTweakSigner?: boolean; // Disable tweaked signer (taproot)
};ConnectionStatus
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';BtcWalletState
The full store state shape.
type BtcWalletState = {
status: ConnectionStatus;
account: WalletAccount | null;
connector: BitcoinConnector | null;
connectorId: string | null;
network: BitcoinNetwork;
error: Error | null;
};BtcWalletConfig
type BtcWalletConfig = {
connectors: BitcoinConnector[];
autoConnect?: boolean;
storage?: Storage;
storageKey?: string;
};Store
The store is built on Zustand with persist and subscribeWithSelector middleware.
State
| Field | Type | Description |
|-------|------|-------------|
| status | ConnectionStatus | Current connection status |
| account | WalletAccount \| null | Connected account info |
| connector | BitcoinConnector \| null | Active connector instance |
| connectorId | string \| null | ID of the active connector |
| network | BitcoinNetwork | Current network |
| error | Error \| null | Last error |
Actions
| Action | Signature | Description |
|--------|-----------|-------------|
| connect | (connector, network?) => Promise<WalletAccount> | Connect to a wallet |
| disconnect | () => Promise<void> | Disconnect current wallet |
| reconnect | (connectors) => Promise<void> | Reconnect to saved wallet |
| setAccount | (account) => void | Update account state |
| setStatus | (status) => void | Update connection status |
| setError | (error) => void | Set error state |
| reset | () => void | Reset to initial state |
Persistence
Only connectorId and network are persisted to storage. Account data is fetched fresh from the connector on reconnect.
Auto-Reconnect
When autoConnect is true (default), the store checks for a saved connectorId on initialization. If found, it automatically reconnects to that wallet using the reconnect() action.
PSBT Utilities
Lightweight PSBT helpers that work in both Node.js and browser environments.
Conversion
import { psbtHexToBase64, psbtBase64ToHex } from 'otx-btc-wallet-core';
const base64 = psbtHexToBase64(psbtHex);
const hex = psbtBase64ToHex(psbtBase64);Validation
import { isValidPsbtHex, isValidPsbtBase64 } from 'otx-btc-wallet-core';
isValidPsbtHex('70736274ff01...'); // true
isValidPsbtBase64('cHNidP8B...'); // trueInfo Extraction
import { getPsbtInfo } from 'otx-btc-wallet-core';
const info = getPsbtInfo(psbtHex);
// { isValid: boolean, version: number | null, inputCount: number | null, outputCount: number | null }Combine PSBTs
import { combinePsbts } from 'otx-btc-wallet-core';
const combined = combinePsbts([psbt1Hex, psbt2Hex]);Sighash Types
import { SighashType, getSighashTypeName } from 'otx-btc-wallet-core';
SighashType.ALL; // 0x01
SighashType.NONE; // 0x02
SighashType.SINGLE; // 0x03
SighashType.ANYONECANPAY; // 0x80
SighashType.ALL_ANYONECANPAY; // 0x81
getSighashTypeName(0x01); // 'ALL'Full Exports
// Config
export { createConfig } from './createConfig';
// Store
export { createStore } from './store';
export type { BtcWalletStore, Store, StoreActions } from './store';
// Types
export type {
BitcoinConnector,
WalletAccount,
AddressType,
MultiAddressAccount,
BitcoinNetwork,
SignPsbtOptions,
SignInput,
BtcWalletConfig,
Config,
BtcWalletState,
ConnectionStatus,
} from './types';
// PSBT Utilities
export {
psbtHexToBase64,
psbtBase64ToHex,
isValidPsbtHex,
isValidPsbtBase64,
getPsbtInfo,
combinePsbts,
SighashType,
getSighashTypeName,
} from './utils';License
MIT
