Repository navigation
[bug] Bitcoin sendTransfer with the Unisat connector sends 1/100,000,000 of the amount #5822
Description
Link to minimal reproducible example
The bug is in the connector itself and is pinned by the existing unit test, so the repo is its own reproduction:
- Connector:
appkit/packages/adapters/bitcoin/src/connectors/UnisatConnector/index.ts
Lines 97 to 100 in 8f9f39f
const result = await this.wallet.sendBitcoin( params.recipient, Number(UnitsUtil.parseSatoshis(params.amount, network)) - Test asserting the wrong value: (
appkit/packages/adapters/bitcoin/tests/connectors/UnisatConnector.test.ts
Lines 139 to 142 in 8f9f39f
const txid = await connector.sendTransfer({ amount: '1500', recipient: 'mock_to_address' }) expect(txid).toBe('mock_txhash') expect(wallet.sendBitcoin).toHaveBeenCalledWith('mock_to_address', 0.000015) sendTransfer({ amount: '1500' })expectssendBitcoin('mock_to_address', 0.000015))
Steps to Reproduce
- Create AppKit with
BitcoinAdapterand thebitcoinnetwork. - Connect the UniSat extension (also reproduces with Bitget Wallet and Binance Web3 Wallet, which use the same connector).
- Call
sendTransferon thebip122provider with an amount in satoshis:const provider = appKit.getProvider<BitcoinConnector>('bip122') await provider.sendTransfer({ recipient: 'bc1q...', amount: '10000' }) // 10,000 sats
- UniSat rejects the request ("Amount is expected to be a positive integer"), because it received
0.0001instead of10000.
Summary
BitcoinConnector.sendTransfer takes amount in satoshis. LeatherConnector and SatsConnectConnector pass it through as satoshis, and OKXConnector converts it to BTC because OKX's send({ value }) takes BTC.
UnisatConnector converts it the same way as OKX:
this.wallet.sendBitcoin(params.recipient, Number(UnitsUtil.parseSatoshis(params.amount, network)))Despite its name, UnitsUtil.parseSatoshis divides by 10 ** decimals, so it returns BTC. But UniSat's sendBitcoin(toAddress, satoshis) expects an integer number of satoshis. As a result, the wallet is asked for 1/100,000,000 of the intended amount, and it rejects the request as a non-integer or dust amount. Also, because parseSatoshis formats with Intl.NumberFormat('en-US'), amounts of 1,000 BTC or more become strings like "1,000", and Number("1,000") is NaN.
Expected: sendBitcoin(params.recipient, Number(params.amount)).
Affected connectors: unisat, bitget, binancew3w (all from UNISAT_CONNECTORS). Still present on main and in 1.8.24.
List of related npm package versions
@reown/appkit1.8.22 (also checkedmain@ 8f9f39f and@reown/appkit-adapter-bitcoin1.8.24)@reown/appkit-adapter-bitcoin1.8.22- UniSat extension 1.7.22
Node.js Version
v25.9.0
Package Manager
pnpm@9.15.9
Activity
linear commentedon Oct 15, 2026
REOWN-4855