ChainGate 1.1.1 — Address validation, custom UTXO transactions & fewer dependencies
This release adds address validation across all networks, custom UTXO transactions with explicit inputs and outputs, improvements to the fee API, and removes heavy third-party dependencies in favor of native implementations.
Address validation
Every network descriptor now exposes isValidAddress() — check whether a string is a valid address for that specific network before creating a transaction:
cg.networks.bitcoin.isValidAddress('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4') // true
cg.networks.ethereum.isValidAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // true
cg.networks.bitcoincash.isValidAddress('bitcoincash:qq...') // true
Works on all network types: UTXO, EVM, Bitcoin Cash, and custom EVM RPC networks. EVM validation includes EIP-55 checksum verification for mixed-case addresses.
Combine with identifyAddressType()
On UTXO networks, identifyAddressType() pairs well with isValidAddress() — it returns the specific script type of a valid address:
cg.networks.bitcoin.identifyAddressType('bc1q...')
// → 'segwit-p2wpkh'
cg.networks.bitcoin.identifyAddressType('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa')
// → 'legacy-p2pkh'
cg.networks.bitcoin.identifyAddressType('bc1p...')
// → 'taproot-p2tr'
Returns 'unknown' for unrecognized formats. Full list of possible types in the documentation.
Custom UTXO transactions
The new createTransaction() method on UTXO connectors lets you build transactions with explicit inputs and outputs — useful for UTXO consolidation, coin selection, batch payments, or any scenario where transfer() is too opinionated:
const bitcoin = cg.connect(cg.networks.bitcoin, wallet)
const tx = bitcoin.createTransaction({
inputs: [
{ txid: 'abc123...', index: 0, amount: cg.networks.bitcoin.amount('0.001'), script: '0014...' }
],
outputs: [
{ address: 'bc1qRecipient...', amount: cg.networks.bitcoin.amount('0.0009') }
]
})
// Fee is implicitly: inputs - outputs
console.log('Fee:', tx.fee().base(), tx.fee().symbol)
const broadcasted = await tx.signAndBroadcast()
Full API
- Inspect:
inputs(),outputs(),fee(),estimatedSizeBytes() - Mutate:
addInput(),removeInput(),addOutput(),removeOutput() - Change handling:
setChangeAddress(address, fee)— auto-computes the change output with dust threshold handling - Fee estimation:
recommendedFees()— fetches network fee rates for the current transaction - Broadcast:
signAndBroadcast()
Listing UTXOs
A new addressUtxos() method on UTXO connectors makes it easy to find UTXOs to spend:
const utxos = await bitcoin.addressUtxos()
Works on Bitcoin, Litecoin, Dogecoin, Bitcoin Cash, and Bitcoin Testnet. Full guide in the custom UTXO transactions documentation.
Fee API changes
setFee() accepts tier objects from recommendedFees(), not string tier names:
const tx = await connector.transfer(amount, to)
const fees = tx.recommendedFees()
// Pass the tier object
tx.setFee(fees.high)
// Or pass custom fee parameters
tx.setFee({ feePerKbSat: 15_000n }) // UTXO
tx.setFee({ maxFeePerGas: 30_000_000_000n, // EVM
maxPriorityFeePerGas: 2_000_000_000n })
UTXO transaction size estimation
estimatedSizeBytes() returns the virtual size in vbytes at the current fee rate:
const size = tx.estimatedSizeBytes()
console.log(size, 'vbytes')
Removed third-party dependencies
We've eliminated heavy third-party libraries and replaced them with native implementations:
bitcore-lib-cash— Bitcoin Cash transaction signing is now implemented from scratch. This removesbitcore-lib-cashand its entire transitive dependency tree (bn.js,elliptic, and others that required version pinning).bchaddrjs— CashAddr encoding and decoding is now a self-contained implementation. Address conversion between CashAddr (bitcoincash:qq...) and legacy Base58Check formats no longer requires an external library.patch-package— No longer needed since there are no third-party packages to patch.
The result is a smaller bundle, fewer transitive dependencies, and no more overrides needed in your package.json.
Migration guide from 1.0
setFee() — use tier objects instead of strings
// 1.0 (incorrect — was documented but never worked with strings)
tx.setFee('normal')
tx.setFee('high')
// 1.1.1 (correct)
const fees = tx.recommendedFees()
tx.setFee(fees.normal)
tx.setFee(fees.high)
Full changelog
| Feature | Description |
|---|---|
isValidAddress() | Validate addresses on all network types |
createTransaction() | Build custom UTXO transactions with explicit inputs/outputs |
addressUtxos() | List UTXOs for a wallet's address on UTXO connectors |
estimatedSizeBytes() | Get virtual transaction size for UTXO transactions |
setFee() API | Accepts tier objects from recommendedFees() |
Removed bitcore-lib-cash | BCH transaction signing reimplemented natively |
Removed bchaddrjs | CashAddr encoding/decoding reimplemented natively |
Removed patch-package | No third-party packages require patching |