Skip to main content

ChainGate 1.1.1 — Address validation, custom UTXO transactions & fewer dependencies

· 3 min read

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 removes bitcore-lib-cash and 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

FeatureDescription
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() APIAccepts tier objects from recommendedFees()
Removed bitcore-lib-cashBCH transaction signing reimplemented natively
Removed bchaddrjsCashAddr encoding/decoding reimplemented natively
Removed patch-packageNo third-party packages require patching