Skip to main content

Transactions

onTransaction() calls you for every confirmed transaction of an address — the ideal hook for payment notifications.

UTXO networks​

On Bitcoin, Litecoin, Dogecoin, Bitcoin Cash and Bitcoin Testnet each event describes one balance change: the transaction, whether the address received or spent, the amount and the resulting balance.

const btc = cg.explore(cg.networks.bitcoin)

btc.onTransaction('bc1q...', ({ txid, received, amount, addressBalance, height }) => {
if (received) {
console.log(`Received ${amount.base()} BTC in ${txid} (block ${height})`)
} else {
console.log(`Sent ${amount.base()} BTC in ${txid}`)
}
console.log('Balance is now', addressBalance.base(), 'BTC')
})
FieldTypeDescription
addressstringThe address being followed
txidstringTransaction id
heightnumberBlock height where the transaction was confirmed
blockIndexnumberPosition of the transaction within the block
receivedbooleantrue when the address received funds, false when it spent them
amountAmountAmount received or spent
addressBalanceAmountBalance of the address right after this transaction

A transaction that both spends from and pays back to the same address (change) produces two events with the same txid.

EVM networks​

On Ethereum and Avalanche an event is sent for every confirmed transaction in which the address appears — as sender, recipient, or in an event emitted by a contract (a token transfer, for example). The event tells you where the activity happened; load the decoded transaction with getAddressHistory():

const eth = cg.explore(cg.networks.ethereum)
const address = '0x...'

eth.onTransaction(address, async ({ height, blockIndex }) => {
console.log(`Activity in block ${height}, position ${blockIndex}`)

const { transactions } = await eth.getAddressHistory(address)
const tx = transactions.find((t) => t.blockHeight === height)
if (tx) {
for (const action of tx.actions) console.log(action.type, action.token?.symbol ?? 'ETH')
}
})
FieldTypeDescription
addressstringThe address being followed
heightnumberBlock height where the transaction was confirmed
blockIndexnumberPosition of the transaction within the block

With a wallet​

Connectors follow the wallet's own address; the address options let you follow any address of an HD wallet:

const wallet = cg.connect(cg.networks.litecoin, myWallet)

wallet.onTransaction(({ received, amount }) => {
console.log(received ? 'Payment received:' : 'Payment sent:', amount.base(), 'LTC')
})

wallet.onTransaction((event) => { /* ... */ }, { index: 1 })

Pending transactions​

onPendingTransaction() calls you for every unconfirmed transaction that touches the address, as soon as it is seen in the mempool — before any block includes it. Use it to show "incoming" payments instantly, and onTransaction() to confirm them.

btc.onPendingTransaction('bc1q...', ({ txid, fee, feeRate, outputs }) => {
console.log('Pending', txid, 'fee:', fee?.base(), 'BTC', `(${feeRate} sat/vB)`)
for (const output of outputs) console.log(' →', output.amount.base(), 'BTC')
})

eth.onPendingTransaction('0x...', ({ hash, from, to, value }) => {
console.log('Pending', hash, from, '→', to, value.base(), 'ETH')
})

The event carries the pending transaction — see Pending transactions for its fields — plus the followed address.

Pending events may be unavailable on some networks

Pending tracking is an optional capability of each network. Subscribing where it is not available succeeds, but no pending events arrive.

Confirming your own transactions​

You do not need onTransaction() to wait for a transfer you just sent: broadcasted.onConfirmed() is notified through the same events and fires as soon as the transaction is included in a block. See Transfer funds.