Krypto-Transaktionen in JavaScript versenden: Bitcoin, Ethereum, Litecoin, Dogecoin & mehr mit ChainGate

Ein praxisnaher JavaScript-Guide zum Versenden von Bitcoin, Ethereum, Avalanche, Litecoin, Dogecoin und Bitcoin Cash aus einem einzigen SDK — von ChainGate.

Bitcoin, Ethereum, Avalanche, Litecoin, Dogecoin and Bitcoin Cash — +6 chains, one JavaScript transfer() call

On-Chain-Daten aus JavaScript zu lesen war schon immer die unangenehme Hälfte der Arbeit. Eine saubere Bitcoin-Balance ziehen — bestätigtes plus unbestätigtes Guthaben, so wie ein Explorer es zeigt — heißt meistens, einen eigenen Indexer zu betreiben oder gegen eine wackelige öffentliche API zu klopfen. Die NFTs und Tokens auflisten, die eine Ethereum- oder EVM-Adresse hält, bedeutet, drei oder vier Explorer-Endpoints zusammenzustricken, jeder mit eigenem Schema, eigenen Rate-Limits und fehlenden Feldern. Und sobald du wirklich eine Transaktion broadcasten willst, bist du zurück bei bitcoinjs-lib für Bitcoin, ethers oder viem auf der EVM-Seite und einem halbgepflegten Fork für Dogecoin und Litecoin. ChainGate deckt all das mit einem einzigen SDK ab.

ChainGate fasst diese Arbeit in einem einzigen JavaScript-SDK zusammen. Als Multi-Chain-Wallet-SDK gebaut, verschickt dieselbe Aufrufform Bitcoin, Ethereum, Avalanche (und jede EVM-Chain), Litecoin, Dogecoin und Bitcoin Cash, liest Adress-Balances aus und listet die Assets, die an einer beliebigen Adresse hängen. Dasselbe Paket läuft in Node.js und im Browser ohne Code-Änderungen — jede Krypto-Primitive ist nativ dabei, keine Polyfills nötig.

Hier der grundlegende Fünf-Zeilen-Send. Der Rest des Guides geht dasselbe Pattern für jede Chain durch und legt anschließend Fee-Schätzung und Balance-Abfragen vor dem Broadcast obendrauf:

import { ChainGate, importWallet } from 'chaingate';

const cg = new ChainGate({ apiKey: 'your-api-key' });
const wallet = importWallet({ phrase: process.env.MNEMONIC });
const btc = cg.connect(cg.networks.bitcoin, wallet);

const tx = await btc.transfer(cg.networks.bitcoin.amount('0.001'), 'bc1qRecipient...');
await tx.signAndBroadcast();

Kurzfassung

  • Ein SDK, alle Chains. Dieselbe transfer()-API deckt Bitcoin, Ethereum, Avalanche, Litecoin, Dogecoin, Bitcoin Cash und jedes EVM-kompatible Netzwerk ab.
  • Läuft unverändert auf Node.js 22+ und in modernen Browsern — kein Buffer- oder crypto-Polyfill-Setup nötig.
  • Fees, Balance und Broadcast sind eingebaut — keine zweite Bibliothek dafür nötig.
  • Signiert wird immer lokal. Dein Private Key verlässt das SDK nicht.

1. Setup: ChainGate installieren und initialisieren

Wähl deinen Paketmanager. Das SDK ist ein einzelnes npm-Paket — einmal installieren und schon kannst du Bitcoin, Ethereum und den Rest aus demselben Import senden, inklusive Types:

# pick your package manager
npm install chaingate
pnpm add chaingate
yarn add chaingate

Hol dir anschließend einen kostenlosen API-Key im ChainGate-Dashboard. Die Anmeldung dauert etwa eine Minute und der kostenlose Tier reicht, um einen Prototypen in Produktion zu bringen. Initialisiere den Client einmal mit diesem Key und nutze ihn für jede Chain wieder:

import { ChainGate } from 'chaingate';

const cg = new ChainGate({ apiKey: process.env.CHAINGATE_API_KEY });

Derselbe Code in Node.js und im Browser. Das Paket läuft auf Node 22+, in modernen Browsern (Vite, Next.js, Webpack 5+) und in Bun ohne Konfiguration, sodass dieselbe Node.js-Blockchain-Library, die du auf dem Server importierst, im Browser des Nutzers läuft. Krypto-Primitiven wie Buffer und randomBytes sind nativ im SDK enthalten — nichts zu polyfillen, nichts zu konfigurieren.

TypeScript-Typen sind enthalten. Es gibt kein @types/chaingate-Paket, weil keines nötig ist — jede öffentliche Klasse, Methode und jedes Event ist im Quellcode vollständig getypt.

2. Bitcoin, Litecoin, Dogecoin und Bitcoin Cash versenden

Bitcoin, Litecoin, Dogecoin und Bitcoin Cash teilen sich dasselbe Buchhaltungsmodell — UTXOs. Der Wallet-Bestand ist die Summe der unspent transaction outputs, die an den Adressen hängen. Zum Versand wählt das Wallet genug UTXOs aus, um den Betrag abzudecken, baut eine neue Transaktion, die sie als Inputs konsumiert, schickt dem Empfänger einen Output, gibt den Rest als Change-Output an sich selbst zurück und zahlt eine Fee in Satoshi pro Kilobyte (oder dem Pendant der jeweiligen Chain).

ChainGate erledigt jeden dieser Schritte — UTXO-Auswahl, Change-Output, Fee-Tier und Signing — hinter einem einzigen transfer()-Aufruf. Du gibst eine Zieladresse und einen Betrag rein, du bekommst eine signierte, sendebereite Transaktion zurück.

Bitcoin aus Node.js oder dem Browser senden

Das Basisbeispiel. Verbinde dein Wallet mit dem Bitcoin-Netzwerk, erstelle die Überweisung, wähle einen Fee-Tier und mach den Broadcast:

import { ChainGate, importWallet, NotEnoughFundsError } from 'chaingate';

const cg = new ChainGate({ apiKey: process.env.CHAINGATE_API_KEY });
const wallet = importWallet({ phrase: process.env.MNEMONIC });

const btc = cg.connect(cg.networks.bitcoin, wallet);
const amount = cg.networks.bitcoin.amount('0.001'); // 0.001 BTC

try {
  const tx = await btc.transfer(amount, 'bc1qRecipient...');
  tx.setFee(tx.recommendedFees().normal);

  const broadcast = await tx.signAndBroadcast();
  console.log('BTC txid:', broadcast.transactionId);
} catch (err) {
  if (err instanceof NotEnoughFundsError) {
    console.error('Not enough BTC for this transfer + fee');
  }
  throw err;
}

Für Testnet-Tests in der Entwicklung tausch cg.networks.bitcoin gegen cg.networks.bitcoinTestnet — der Rest bleibt gleich.

Litecoin aus Node.js oder dem Browser senden

Derselbe Code, anderes Netz. Der Diff zum Bitcoin-Snippet ist buchstäblich ein Identifier:

const ltc = cg.connect(cg.networks.litecoin, wallet);
const amount = cg.networks.litecoin.amount('0.1'); // 0.1 LTC

const tx = await ltc.transfer(amount, 'ltc1qRecipient...');
tx.setFee(tx.recommendedFees().normal);
await tx.signAndBroadcast();

Litecoin nutzt standardmäßig ltc1q…-SegWit-Adressen und bestätigt Blöcke alle zweieinhalb Minuten — etwa viermal schneller als Bitcoin —, was es für Low-Value-Zahlungen beliebt macht, bei denen Settlement-Geschwindigkeit wichtiger ist als Sicherheitstiefe.

Dogecoin aus Node.js oder dem Browser senden

Selber Diff, andere Chain:

const doge = cg.connect(cg.networks.dogecoin, wallet);
const amount = cg.networks.dogecoin.amount('100'); // 100 DOGE

const tx = await doge.transfer(amount, 'DRecipientAddress...');
tx.setFee(tx.recommendedFees().normal);
await tx.signAndBroadcast();

Das JavaScript-Ökosystem von Dogecoin hinkt dem Rest der UTXO-Familie hinterher. Die meisten populären bitcoinjs-lib-Forks wurden seit Jahren nicht aktualisiert, und die wenigen gepflegten Alternativen sind privat. ChainGate ist heute eine der ganz wenigen Optionen mit produktionsreifem Dogecoin-Support in JavaScript.

Bitcoin Cash aus Node.js oder dem Browser senden

Bitcoin Cash nutzt standardmäßig CashAddr-Adressen, das SDK akzeptiert aber auch das Legacy-Format — du kannst beide Varianten in transfer() einfügen, das Netzwerk bestätigt sie:

const bch = cg.connect(cg.networks.bitcoincash, wallet);
const amount = cg.networks.bitcoincash.amount('0.05'); // 0.05 BCH

// CashAddr or legacy — both work
const tx = await bch.transfer(amount, 'bitcoincash:qpRecipient...');
tx.setFee(tx.recommendedFees().normal);
await tx.signAndBroadcast();

Die Adressvalidierung ist bidirektional: cg.networks.bitcoincash.isValidAddress() liefert für beide Formate true, du musst also Nutzereingaben vor dem Versand nicht normalisieren.

UTXO-Sends im Browser

Alle vier UTXO-Snippets oben laufen unverändert in einem Vite-, Next.js- oder Webpack-5-Bundle — derselbe Import funktioniert auf dem Client, dasselbe Wallet signiert lokal, ohne die API zu kontaktieren.

Eine Sicherheitsanmerkung: Lade Production-Private-Keys niemals direkt ins Frontend. Halte das Signieren entweder serverseitig und schick nur den Broadcast aus dem Browser, oder lass den Nutzer den Key über einen Wallet-artigen Flow liefern, den er kontrolliert.

3. Ethereum und EVM-Chains versenden

Ethereums Account-Modell ist anders — keine UTXOs, sondern eine Adresse mit Balance und einem monoton steigenden Nonce. ChainGate verbirgt diesen Unterschied hinter demselben transfer()-Aufruf, den du auf Bitcoin verwendet hast. Die Unterschiede (Nonce-Verwaltung, EIP-1559-Base-Fee + Tip, Gas-Limit) werden für dich berechnet:

const eth = cg.connect(cg.networks.ethereum, wallet);
const amount = cg.networks.ethereum.amount('0.01'); // 0.01 ETH

const tx = await eth.transfer(amount, '0xRecipient...');
tx.setFee(tx.recommendedFees().normal);

const broadcast = await tx.signAndBroadcast();
console.log('ETH txHash:', broadcast.transactionId);

Avalanche mit Node.js oder im Browser versenden

Avalanches C-Chain ist als First-Class-Netzwerk neben Ethereum verdrahtet — dieselbe Aufrufform, dasselbe Wallet, Beträge in AVAX. Das Diff gegen das Ethereum-Snippet ist genau ein Identifier:

const avax = cg.connect(cg.networks.avalanche, wallet);
const amount = cg.networks.avalanche.amount('1'); // 1 AVAX

const tx = await avax.transfer(amount, '0xRecipient...');
tx.setFee(tx.recommendedFees().normal);
await tx.signAndBroadcast();

Die C-Chain finalisiert Blöcke in etwa zwei Sekunden und läuft auf demselben EIP-1559-Fee-Modell wie Ethereum — AVAX-Transfers settlen entsprechend schnell, und die Ausgabe von recommendedFees() ist identisch geformt. Genau das macht Avalanche zu einer beliebten Wahl für Zahlungen mit hohem Durchsatz, bei denen Ethereum-Gas den Nutzer aus dem Markt drängen würde.

Dasselbe Wallet, dasselbe SDK, jede EVM-Chain. Die gehosteten RPC-URLs decken Polygon, Arbitrum, Base, BNB Chain und Sonic von Haus aus ab; für jede andere EVM-Network — Optimism, Linea, Scroll, Gnosis, dein eigener Node, ein Testnet — gib die JSON-RPC-URL direkt an evmRpc(). POL auf Polygon zu senden ist ein Einzeiler-Diff:

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

const pol = cg.connect(polygon, wallet);
const amount = polygon.amount('5'); // 5 POL

const tx = await pol.transfer(amount, '0xRecipient...');
tx.setFee(tx.recommendedFees().normal);
await tx.signAndBroadcast();

Nonce-Handling läuft automatisch. Das SDK liest vor dem Signieren den letzten pending Nonce aus dem gewählten RPC, du musst ihn selbst nicht nachhalten. Die Fee-Konstruktion läuft auf Chains, die es unterstützen, standardmäßig nach EIP-1559 (maxFeePerGas + maxPriorityFeePerGas) und fällt bei den anderen auf Legacy-Gas-Pricing zurück.

Die chainId, die du an evmRpc() übergibst, muss die sein, die der RPC-Endpunkt selbst meldet, sonst signiert das SDK für das falsche Netzwerk. Die EVM-Chain-ID-Liste hat die Nummer für Polygon, Arbitrum, Base, Optimism und 35 weitere Netzwerke und Testnets und zeigt, wie du sie direkt aus jeder RPC-URL ausliest.

Antwortet der Node auf einen Broadcast mit "nonce too low", "replacement transaction underpriced" oder "insufficient funds for gas * price + value", erklärt der Leitfaden zu Ethereum-Transaktionsfehlern, was jede Meldung bedeutet und welche davon Gas kosten.

Browser-Support ist identisch zu den UTXO-Chains. Genau dieser Code gehört hinter den 'Send'-Button in einer dApp.

4. Transaktionsfees vor dem Versand schätzen

Zeig die Fee immer vor dem Broadcast. Nutzer hassen Überraschungen, festsitzende Transaktionen kosten Zeit, und ein 'Review and Confirm'-Schritt verwandelt einen One-Shot-UI-Flow in etwas, dem ein Nutzer wirklich vertraut.

ChainGate exponiert auf jeder Chain dieselbe Methode recommendedFees() — sie liefert vier Tiers (low, normal, high, maximum) mit den jeweils passenden Zahlen. Auf Bitcoin bekommst du eine feePerKbSat-Rate und das geschätzte Total in Satoshi; auf Ethereum und anderen EVM-Chains bekommst du EIP-1559-maxFeePerGas und maxPriorityFeePerGas als bigint in wei plus ein geschätztes Bestätigungsfenster:

// Bitcoin — fee rate in sat/kB, plus the total estimated fee in satoshis
const btcTx = await btc.transfer(cg.networks.bitcoin.amount('0.01'), 'bc1q...');
const btcFees = btcTx.recommendedFees();

console.table({
  low:    { satPerKb: btcFees.low.feePerKbSat,    feeSat: btcFees.low.estimatedFeeSat,    enough: btcFees.low.enoughFunds },
  normal: { satPerKb: btcFees.normal.feePerKbSat, feeSat: btcFees.normal.estimatedFeeSat, enough: btcFees.normal.enoughFunds },
  high:   { satPerKb: btcFees.high.feePerKbSat,   feeSat: btcFees.high.estimatedFeeSat,   enough: btcFees.high.enoughFunds },
});

// Ethereum — EIP-1559 numbers in gwei
const ethTx = await eth.transfer(cg.networks.ethereum.amount('0.1'), '0x...');
const ethFees = ethTx.recommendedFees();
const toGwei = (wei) => Number(wei) / 1e9;

console.table({
  low:     { gwei: toGwei(ethFees.low.maxFeePerGas),     sec: ethFees.low.estimatedConfirmationSecs },
  normal:  { gwei: toGwei(ethFees.normal.maxFeePerGas),  sec: ethFees.normal.estimatedConfirmationSecs },
  high:    { gwei: toGwei(ethFees.high.maxFeePerGas),    sec: ethFees.high.estimatedConfirmationSecs },
  maximum: { gwei: toGwei(ethFees.maximum.maxFeePerGas), sec: ethFees.maximum.estimatedConfirmationSecs },
});

Das Pattern, das in Produktion funktioniert: Transaktion bauen, recommendedFees() aufrufen, dem Nutzer die vier Tiers zeigen, ihn wählen lassen und dann signAndBroadcast() aufrufen. Das Transaktionsobjekt bleibt zwischen Schätzung und Broadcast im Speicher — kein erneutes Bauen nötig.

5. Balance vor dem Versand prüfen

Eine Balance-Prüfung gehört ganz an den Anfang jedes Send-Flows. Sie fängt Tippfehler ab, vermeidet vergeudetes Gas für eine fehlschlagende Transaktion und gibt dem Nutzer eine Zahl, gegen die er prüfen kann. Jede Chain bietet denselben Einzeiler — übergib eine Adresse (oder nutze das verbundene Wallet) und du bekommst die bestätigte Balance plus, wo unterstützt, den unbestätigten Anteil:

// Ethereum — confirmed balance + live USD price
const eth = cg.connect(cg.networks.ethereum, wallet);
const ethBalance = await eth.addressBalance();
const ethUsd = await ethBalance.confirmed.toCurrency('usd');
console.log(`${ethBalance.confirmed.base()} ETH ($${ethUsd})`);

// Bitcoin — confirmed and unconfirmed split
const btc = cg.connect(cg.networks.bitcoin, wallet);
const btcBalance = await btc.addressBalance();
console.log(`Confirmed:   ${btcBalance.confirmed.base()} BTC`);
console.log(`Unconfirmed: ${btcBalance.unconfirmed.base()} BTC`);

Kombiniert mit der Fee-Schätzung sind drei Aufrufe der komplette Pre-Flight — Balance, Fee, dann Send. Verkabel das einmal und jeder Send-Flow in deiner App bekommt dieselbe Pre-Send-Validierung gratis, egal ob du eine Crypto-Balance aus Node.js auf dem Server oder im Browser prüfst.

6. ChainGate vs. bitcoinjs-lib, ethers und andere Alternativen

ChainGate will nicht jede Low-Level-Bibliothek davor ersetzen. Jede hat ihre klare Aufgabe. So sehen die Trade-offs aus, wenn man Transaktionen über mehr als eine Chain verschicken muss:

FähigkeitChainGatebitcoinjs-libethers / viemEigenbau pro Chain
Unterstützte ChainsBTC, ETH, AVAX+EVM, LTC, DOGE, BCHNur BitcoinNur EVM1 pro Bibliothek
Zeilen für einen BTC-Send~5~40+n/avariabel
Browser-fähigJa — out of the boxPolyfills nötigJaVariabel
Eingebaute Fee-SchätzungJaNeinTeilweiseNein
TypeScript-TypenFirst-classCommunityJaVariabel

Bleib bei bitcoinjs-lib oder ethers, wenn du Byte-genaue Kontrolle über die Transaktionsform brauchst oder deine App nur eine Chain anspricht und Bundle-Größe entscheidend ist. Wechsle zu ChainGate, wenn du mehrere Chains gleichzeitig jonglierst, unter Zeitdruck stehst oder ein kleines Team führst, das sich keine Spezialisierung pro Blockchain leisten kann.

7. Preise und Free-Stufe

Die Free-Stufe ist absichtlich großzügig — jeder Plan, auch der Free-Plan, bringt das komplette SDK mit: Balances, Asset-Listings, Fee-Schätzung, Signing und Broadcast für jede unterstützte Chain. Es reicht, einen Prototypen zu shippen, ein privates Projekt zu betreiben oder ein internes Tool in Produktion zu bringen. Bei der Anmeldung wird keine Kreditkarte verlangt.

Die kostenpflichtigen Stufen heben die Rate-Limits an und liefern Priority-Support und Burst-Kapazität. Upgrades laufen mit einem Klick im Dashboard.

Schau dir die Preisseite für aktuelle Zahlen und den Upgrade-Pfad an.

8. Wie es weitergeht

Du hast das Modell: ein SDK, mehrere Chains und dieselbe Fünf-Zeilen-Form auf jeder davon. Von hier aus deckt die Dokumentation den Rest der Oberfläche ab — Message-Signing, ERC-20-Transfers, NFT-Bewegungen, dekodierte Transaktionshistorie. Die Beispiele auf GitHub sind ein guter Einstieg mit End-to-End-Rezepten zum Kopieren. Und das API-Dashboard ist einen Klick entfernt, sobald du dir einen Key holen und etwas ausliefern willst. Wer tiefer in die Mechanik hinter einer Fee einsteigen möchte, findet im Begleit-Guide zu Ethereum-Gas auseinandergenommen, woher die Zahlen aus recommendedFees() wirklich kommen. Der Guide zu Transaktions-Hashes erklärt, wie die transactionId aus signAndBroadcast() auf jeder Chain aussieht und wie du sie in einem Block Explorer prüfst.

Häufig gestellte Fragen

Hält ChainGate meine Private Keys?
Nein. Wallet-Konstruktion, Key-Ableitung und Signing laufen lokal auf deinem Gerät. Die ChainGate-API nimmt nur Read-Calls entgegen und broadcastet bereits signierte Roh-Transaktionen — deine Seed Phrase und dein Private Key verlassen das SDK nicht.
Kann ich ChainGate im Browser verwenden?

Ja — jedes Beispiel in diesem Guide läuft unverändert in einem Vite-, Next.js- oder Webpack-5-Bundle. Das SDK bringt eine eigene browserkompatible Krypto-Implementierung mit, also gibt es nichts zusätzlich zu installieren.

Welche Netzwerke werden unterstützt?

ChainGate liefert vollen API-Support für Bitcoin, Bitcoin Testnet, Litecoin, Dogecoin, Bitcoin Cash, Ethereum und Avalanche, gehostete JSON-RPC-Endpoints für Polygon, Arbitrum, Base, BNB Chain und Sonic sowie Bring-your-own-RPC für jede andere EVM-Chain — inklusive Optimism, Linea, Scroll, Gnosis, Testnets und selbstgehosteten Nodes. Die vollständige Matrix steht in der Dokumentation.

Kann ich Testnet-Transaktionen senden?

Ja — es gibt keinen speziellen Testnet-Flag. Übergib das Testnet-Network an denselben cg.connect()-Aufruf wie auf Mainnet: für Bitcoin ist das cg.networks.bitcoinTestnet; für ein EVM-Testnet übergib URL und Chain-ID des Testnets an cg.networks.evmRpc({ rpcUrl, chainId, name, symbol }). Der Rest des Codes ist identisch mit den Mainnet-Beispielen aus diesem Guide.

Was passiert, wenn eine Transaktion fehlschlägt?

Das SDK liefert einen typisierten Error, den du fangen und auswerten kannst. Die meisten Probleme vor dem Broadcast lassen sich beheben — das Transaktionsobjekt wird beim Retry mit frischem Nonce oder neuer UTXO-Auswahl wieder zusammengebaut, sodass ein zweiter Versuch in der Regel durchgeht.

Ist ChainGate Open Source?

Das JavaScript-SDK, das auf deiner Maschine signiert und broadcastet, ist auf GitHub unter MIT-Lizenz veröffentlicht — lies den Quellcode, kopiere ihn in dein Repo oder forke ihn. Die ChainGate-API dahinter ist ein Managed Service, der den Rest für dich erledigt. Die meisten Teams nutzen das Open-Source-SDK mit der gehosteten API, du kannst das SDK aber auf jede RPC-URL zeigen, die du kontrollierst, wenn du lieber deine eigene Infrastruktur betreibst.

Warum braucht ChainGate einen API Key?
Der API Key authentifiziert die Aufrufe ans ChainGate-Backend — und genau das übernimmt die Teile, die das SDK selbst nicht erledigen kann: JSON-RPC-Anfragen zur jeweiligen Chain verarbeiten, UTXOs und Balances abfragen und signierte Transaktionen broadcasten. Das Signieren passiert weiterhin lokal mit deinem Wallet; der Key autorisiert nur den Read- und Broadcast-Traffic, der durch die ChainGate-Infrastruktur läuft. Der kostenlose Plan stellt einen Key im Dashboard ohne Kreditkarte aus.

Baue mit ChainGate

Setze diese Ideen in Code um — ChainGate liefert Wallets, Transaktionen und verwaltetes RPC für Ethereum und 20+ weitere Blockchains in einer einzigen Bibliothek.