Skip to main content

ChainGate 1.0 is here — One SDK, every blockchain, zero compromises

· 6 min read

ChainGate 1.0 is the first TypeScript SDK that lets you create wallets, sign transactions, query balances, and explore blockchain data across every major network — with a single, unified API. No ethers.js. No chain-specific boilerplate. Just npm install chaingate and you're building.

This isn't a minor version bump — it's a complete rewrite from the ground up. New wallet architecture, new connector system, new transaction pipeline, native crypto signing, and first-class support for both EVM and UTXO chains. If you've been looking for a single library to replace your patchwork of blockchain tools, this is it.

What changed and why

The 0.x library grew organically: wallets knew about currencies, currencies had their own utils, React was bolted on, and ethers.js handled all EVM heavy lifting. It worked, but it didn't scale well and leaked complexity.

1.0 separates concerns cleanly:

  • Wallets only manage keys and derivation
  • Networks define blockchain parameters and provide address derivation
  • Connectors bridge a wallet + network into actionable operations (balance, transfer, history)
  • Explorers handle raw API/RPC calls independently of wallets

Highlights

Ethers.js is gone

All EVM transaction signing, RLP encoding, ABI encoding, and message signing are now implemented from scratch using @noble/curves and @noble/hashes. Smaller bundle, fewer dependencies, full control.

New wallet types

0.x1.0
PhraseWalletPhraseWallet
SeedWalletSeedWallet
PrivateKeyWalletPrivateKeyWallet
XprivWallet (new)
XpubWallet (view-only, new)
PublicKeyWallet (view-only, new)

View-only wallets let you derive addresses and check balances without ever touching a private key.

Wallet creation API

The initializeWallet namespace is gone. Everything is now top-level:

// 0.x
import { initializeWallet } from 'chaingate'
const { phrase, wallet } = initializeWallet.create({ apiKey })
const wallet2 = initializeWallet.fromPhrase({ apiKey, phrase: '...' })

// 1.0
import { newWallet, importWallet } from 'chaingate'
const { phrase, wallet } = newWallet()
const wallet2 = importWallet({ phrase: '...' })

Or auto-detect the format:

import { createWalletFromString } from 'chaingate'
const wallet = createWalletFromString('xpub6C...') // -> XpubWallet

ChainGate client + connectors

Instead of wallet.currency('bitcoin'), you now create a client and connect:

// 0.x
const wallet = initializeWallet.fromPhrase({ apiKey, phrase })
const btc = wallet.currency('bitcoin')
const address = await btc.getAddress()
const balance = await btc.getBalance()
const tx = await btc.createTransfer(to, amount)

// 1.0
import { ChainGate, importWallet } from 'chaingate'
const cg = new ChainGate({ apiKey })
const wallet = importWallet({ phrase: '...' })
const btc = cg.connect(cg.networks.bitcoin, wallet)
const address = await btc.address()
const balance = await btc.addressBalance()
const tx = await btc.transfer(amount, to)

Custom EVM networks via RPC

Any EVM chain — not just the ones we index:

const myChain = cg.networks.evmRpc({
rpcUrl: 'https://rpc.mychain.io',
chainId: 12345,
name: 'MyChain',
symbol: 'MYC',
})
const connector = cg.connect(myChain, wallet)
await connector.transfer(amount, to)

Auto-detects EIP-1559 vs legacy. No ChainGate API required for these networks.

Transaction lifecycle

The flow is now explicit and inspectable:

const tx = await connector.transfer(amount, to)
const fees = await tx.recommendedFees() // { low, normal, high, maximum }
tx.setFee('high') // or tx.setFee({ gasPrice: ... })
const enough = await tx.enoughFunds()
const broadcasted = await tx.signAndBroadcast()

// Poll for confirmation with a cancel handle
const cancel = broadcasted.onConfirmed((details) => {
console.log('Confirmed!', details)
})
// cancel() to stop polling

Token & NFT transfers

Built-in ERC-20, ERC-721 and ERC-1155 support without ABI imports:

await connector.transferToken(tokenAddress, amount, to)
await connector.transferNft(contractAddress, tokenId, to)
await connector.transferErc1155(contractAddress, tokenId, amount, to)

Message signing on every network

// EVM
const sig = cg.networks.ethereum.signMessage('hello', privateKey)
const valid = cg.networks.ethereum.verifyMessage('hello', sig, address)

// UTXO — uses the correct magic prefix per chain
const sig = cg.networks.bitcoin.signMessage('hello', privateKey)
const valid = cg.networks.bitcoin.verifyMessage('hello', sig, address)

Also available as standalone functions: signEvmMessage, verifyEvmMessage, signUtxoMessage, recoverUtxoPublicKey.

Encryption rework

  • AES-256-GCM with PBKDF2 (600K iterations)
  • wallet.encrypt(password, askForPassword) — encrypts in place
  • The derived CryptoKey is cached; the password is never stored
  • Every decrypt re-encrypts with a fresh IV
  • Direct access to encrypted secrets throws EncryptedAccessError

UTXO local cache

Chain multiple UTXO transactions without waiting for the API to reflect previous ones:

const tx1 = await btc.transfer(amount1, addr1)
const b1 = await tx1.signAndBroadcast()
// Immediately spend the change output
const tx2 = await btc.transfer(amount2, addr2)
const b2 = await tx2.signAndBroadcast()

RPC URL proxy

Pre-built RPC URLs for 12 networks, authenticated via your API key:

cg.rpcUrls.ethereum // https://api.chaingate.dev/rpc/ethereum?api_key=...
cg.rpcUrls.bitcoin // https://api.chaingate.dev/rpc/bitcoin?api_key=...
cg.rpcUrls.get('sonic')

supports() type guard

import { supports } from 'chaingate'
if (supports(wallet, 'hdwallet')) {
wallet.derive(0) // TypeScript knows this is an HDWallet
}
if (supports(wallet, 'viewonly')) {
// read-only operations only
}

Removed

  • React integration — Moved to a separate package chaingate-react with ChainGateProvider and WalletProvider contexts.

  • initializeWallet / castWallet namespaces — Replaced by top-level functions.

  • CurrencyWallet / CurrencyUtils pattern — Replaced by Connectors + Explorers.

  • CurrencyAmount class — Replaced by the new Amount class (bigint-based, with base(), min(), toCurrency()).

  • initializeUtils / CurrencyUtilsProvider — Use cg.explore(network) for wallet-free queries.

  • AllCurrencies array — Use cg.networks to iterate available networks.

  • FiatCurrencies array — Fiat conversion is now handled via Amount.toCurrency().

  • Native EVM networks (except Ethereum) — Polygon, Arbitrum, Base, Avalanche, BNB, and Sonic (formerly Fantom) are no longer built-in networks with dedicated API endpoints. The native support for these chains didn't add meaningful value over standard RPC access. You can still use all of them exactly as before by combining cg.networks.evmRpc() with ChainGate's RPC endpoints:

    const polygon = cg.networks.evmRpc({
    rpcUrl: cg.rpcUrls.polygon,
    chainId: 137,
    name: 'Polygon',
    symbol: 'POL',
    })

    const connector = cg.connect(polygon, wallet)

    Wallets, transfers, balances, and everything else work identically. Ethereum remains natively supported with full API coverage (transaction history, token balances, NFT metadata, etc.).


Migration cheat sheet

Task0.x1.0
Create walletinitializeWallet.create({ apiKey })newWallet()
Import from phraseinitializeWallet.fromPhrase({ apiKey, phrase })importWallet({ phrase })
Import from xpubimportWallet({ xpub })
Auto-detect importcreateWalletFromString(input)
Access a blockchainwallet.currency('bitcoin')cg.connect(cg.networks.bitcoin, wallet)
Get addresscurrency.getAddress()connector.address()
Get balancecurrency.getBalance()connector.addressBalance()
Create transfercurrency.createTransfer(to, amt)connector.transfer(amt, to)
Get feestx.getSuggestedFees()tx.recommendedFees()
Broadcasttx.broadcast('high')tx.setFee('high'); tx.signAndBroadcast()
Wait for confirmbroadcasted.waitToBeConfirmed()broadcasted.onConfirmed(cb)
Serialize walletwallet.serialize()wallet.serialize() (same)
DeserializeinitializeWallet.deserialize(...)deserializeWallet(data, askPw)
Validate phraseinitializeWallet.checkPhrase(p)isValidPhrase(p)
Amount creationutils.amount('0.1', 'btc')network.amount('0.1')
Fiat conversionutils.amountFiat('10', 'usd')network.amountFromCurrency('usd', 10)
Encrypt walletConstructor option { encrypt }wallet.encrypt(password, askFn)
Message signingcurrency.signMessage(msg)network.signMessage(msg, privKey)
Query without walletinitializeUtils({ apiKey })cg.explore(network)

Node.js requirement

1.0 requires Node.js >= 22. We use native crypto.subtle directly — no polyfills.


ChainGate 1.0 is production-ready, fully typed, and built to be the last blockchain SDK you'll ever need. Whether you're building a wallet, a DeFi dashboard, a payment gateway, or just need to query a balance — it's one import away.

npm install chaingate

Get your free API key at api.chaingate.dev/dashboard, star us on GitHub, and join the Discord to tell us what you're building.