Quantum Coin logo Quantum Coin

Integrating with the Quantum Coin blockchain

Quantum Coin is EVM-compatible, so most Ethereum tooling and JSON-RPC knowledge carries over. Start with the differences below, then pick your path: Developers build and invoke smart contracts, Exchanges & Institutions create wallets, sign and send transactions, and watch deposits programmatically. Both paths link into the shared reference sections further down.

Important differences from Ethereum

Everything else on this page assumes you know these. They apply equally to developers and exchanges.

  • Addresses are 32 bytes, not 20. An address is 66 characters in hex including the 0x prefix. Hex case does not matter: the upper-case and lower-case forms of an address are both accepted and refer to the same account; there is no EIP-55 mixed-case checksum. Validate with isAddressValid (quantum-coin-js-sdk) or isAddress (quantumcoin).
  • Post-quantum account keys. Accounts are secured by a hybrid signature: Ed25519 + ML-DSA (FIPS 204) + SLH-DSA (FIPS 205). Key type 3 is the default; key type 5 uses NIST security level 5 parameters. See Quantum Resistance.
  • Gas price is fixed by the chain, not chosen by the sender. The price per gas depends on the signing scheme of the transaction. There is no fee auction and no EIP-1559 base fee. A basic transfer uses 21000 gas and costs about 100 coins with the default key type. See Gas fees.
  • Immediate finality. Consensus is BFT proof-of-stake. A committed block is final; there are no reorganizations, so one confirmation is sufficient. See Consensus.
  • Chain ID is 123123 on mainnet. The local devnet uses the same chain ID.
  • Optional remarks field. Transactions can carry up to 32 bytes of remarks. Do not put sensitive data there.
  • Wallet formats differ. Seed phrases are 32 words (key type 3) or 36 words (key type 5), not BIP-39. Encrypted keystore JSON files are shared across the official wallets and both SDKs. There are no HD wallets, no EIP-712 typed data signing and no ENS. See SDKs.
  • ABI encoding is the same, except for addresses. Function selectors and event topics are identical to Ethereum because canonical signatures are the same strings. A 32-byte address fills a whole ABI word instead of being left-padded. Use the QuantumCoin Solidity compiler and SDKs, which handle this. See Solidity Docs.
  • Signatures are not r/s/v. A signature is a multi-kilobyte blob whose first byte identifies the scheme and which embeds the signer's public key. There is no ecrecover; verification returns the signer address from the embedded key. Keys, signatures and transactions are therefore larger than on Ethereum.

For Developers

Start at the Builder: builder.quantumcoin.org

The Builder is a browser-based development environment for Quantum Coin. Write Solidity, compile it with the QuantumCoin compiler, create (deploy) contracts and invoke their methods, all from the browser with no local toolchain to install. You can also use the SDKs to build your own custom tools and services on top of Quantum Coin, such as bots, payment services, indexers or wallets.

Recommended flow:

  1. Open the Builder and write or paste your Solidity contract. Read the Solidity Docs for the QuantumCoin-specific changes, mainly the 32-byte address type.
  2. Compile in the Builder. It uses the same compiler as the @quantumcoin/solc npm package, so the ABI and bytecode are interchangeable with your local build.
  3. Create the contract and invoke its methods from the Builder, on mainnet or on a local devnet.
  4. Verify the transaction and contract on the Block Explorer.
  5. When you need the contract inside an application, use an SDK: quantumcoin for an ethers.js-style experience, or quantum-coin-js-sdk for low-level signing and ABI packing. Point either at the public JSON-RPC endpoint, your devnet or your own node.
  6. Budget for gas fees: contract calls need an explicit gasLimit, and the price per gas is fixed by the chain.

Go deeper:

For Exchanges & Institutions

Sign programmatically with quantum-coin-js-sdk

Use quantum-coin-js-sdk to create wallets and sign transactions in your own systems. The SDK is offline-only: it never makes network calls, so signing can run on an isolated host. Broadcast the signed transaction over JSON-RPC with eth_sendRawTransaction, either to the community endpoint or to your own node.

Recommended flow:

  1. Choose an RPC endpoint. The community endpoint is https://public.rpc.quantumcoinapi.com (see JSON-RPC API). Running your own node is optional but recommended for production; follow Connecting to Mainnet and enable HTTP RPC as described in Running your own node.
  2. Create and open wallets with quantum-coin-js-sdk. Call newWallet to create a wallet and serializeEncryptedWallet to get an encrypted keystore JSON for storage; reopen it later with deserializeEncryptedWallet and check it with verifyWallet. Validate customer withdrawal addresses with isAddressValid; addresses are 32 bytes (see differences). SDK examples: create an encrypted wallet, open an encrypted wallet, seed words and address validation.
  3. Sign and send transactions with quantum-coin-js-sdk. This is the core of the integration. Read the nonce with eth_getTransactionCount, build a TransactionSigningRequest, sign it with signRawTransaction (offline), POST the result to eth_sendRawTransaction, then poll eth_getTransactionReceipt. The hash returned by the node must equal the txnHash from the SDK. SDK examples: sign and send with signRawTransaction, sign and send a token (contract) transaction. See also the two code toggles below.
  4. Detect deposits. Poll eth_blockNumber and fetch each new block with eth_getBlockByNumber (full transactions), matching to against your deposit addresses. For tokens, use eth_getLogs on the token's Transfer event; topics are the same as on Ethereum. A committed block is final, so one confirmation is enough (see Consensus).
  5. Budget fees. The gas price is fixed by the chain per signing scheme; a basic transfer uses 21000 gas and costs about 100 coins with the default key type. Use getGasPrice to compute it (see Gas fees). Keep enough coins in hot wallets to cover fees.
// npm install quantum-coin-js-sdk
const qcsdk = require("quantum-coin-js-sdk");

async function main() {
  await qcsdk.initialize(new qcsdk.Config(123123)); // mainnet chain id

  // Create a wallet (key type 3 is the default)
  const wallet = qcsdk.newWallet(null);
  if (typeof wallet === "number") throw new Error("newWallet failed: " + wallet);
  console.log("address:", wallet.address); // 0x + 64 hex characters

  // Encrypted keystore JSON, same format as the official wallets.
  // Passphrase must be at least 12 characters. scrypt makes this take a while.
  const keystoreJson = qcsdk.serializeEncryptedWallet(wallet, "a-long-passphrase-123!");
  // ... store keystoreJson in your secure key store ...

  // Open the wallet again later
  const reopened = qcsdk.deserializeEncryptedWallet(keystoreJson, "a-long-passphrase-123!");
  console.log("verified:", qcsdk.verifyWallet(reopened)); // true
}

main().catch(console.error);
Examples: example-wallet.js, example-wallet-version4.js
const qcsdk = require("quantum-coin-js-sdk");

const RPC_URL = "https://public.rpc.quantumcoinapi.com"; // or your own node, e.g. http://127.0.0.1:8545
const CHAIN_ID = 123123;

async function rpc(method, params) {
  const res = await fetch(RPC_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
  });
  const json = await res.json();
  if (json.error) throw new Error(json.error.message);
  return json.result;
}

async function main() {
  await qcsdk.initialize(new qcsdk.Config(CHAIN_ID));

  // Hot wallet from your key store (see the wallet example above)
  const wallet = qcsdk.deserializeEncryptedWallet(keystoreJson, passphrase);

  const to = "0x0000000000000000000000000000000000000000000000000000000000001000"; // 66 characters
  if (!qcsdk.isAddressValid(to)) throw new Error("invalid address");

  const nonce = parseInt(await rpc("eth_getTransactionCount", [wallet.address, "pending"]), 16);
  const valueInWei = BigInt("1000000000000000000"); // 1 coin; a 0x hex string also works

  // (wallet, to, valueInWei, nonce, data, gasLimit, remarks, chainId, signingContext)
  const request = new qcsdk.TransactionSigningRequest(wallet, to, valueInWei, nonce, null, 21000, null, CHAIN_ID, null);
  const signed = qcsdk.signRawTransaction(request); // synchronous, offline
  if (signed.resultCode !== 0) throw new Error("signing failed: " + signed.resultCode);

  const txHash = await rpc("eth_sendRawTransaction", [signed.txnData]);
  if (txHash !== signed.txnHash) throw new Error("node returned an unexpected hash");
  console.log("sent:", txHash);

  // Poll eth_getTransactionReceipt until it is not null; status 0x1 means success.
}

main().catch(console.error);
Examples: example-create-contract.js, example-token-pack-unpack.js

Go deeper:

SDKs and compiler

Two JavaScript SDKs are published on npm. Both are maintained by the community and share the same underlying post-quantum cryptography.

quantumcoin.js (npm: quantumcoin) quantum-coin-js-sdk (npm: quantum-coin-js-sdk)
Who it is for Developers who are used to ethers.js. The API surface follows ethers.js v6 (Provider, Wallet, Contract, ContractFactory, Interface, units), so dapp and service code ports with few changes. Start with example.js. Typically exchanges and institutions that prefer lower-level, simpler functionality: a small set of plain functions for wallets, offline signing and ABI packing, with no network code inside the SDK. Start with example.js.
Install npm install quantumcoin npm install quantum-coin-js-sdk
API style Classes and promises, ethers.js v6 compatible. Call Initialize() once before anything else. See the API reference. Plain functions returning result codes (0 = success). Call initialize() once before anything else. See the README.
Create and open wallets Wallet.createRandom, Wallet.fromPhrase, Wallet.fromSeed, encrypted keystore JSON via encryptSync / Wallet.fromEncryptedJsonSync. Example: wallet-offline.js. newWallet, newWalletSeedWords, openWalletFromSeedWords, serializeEncryptedWallet / deserializeEncryptedWallet, verifyWallet. Examples: example-wallet.js, example-wallet-version4.js.
Sign transactions wallet.signTransaction (offline) and wallet.sendTransaction; signMessage / verifyMessage for messages. Examples: offline-signing.js, sign-message.js. TransactionSigningRequest + signRawTransaction (synchronous, offline); sign / verify for raw messages. Example: example-create-contract.js.
Submit transactions provider.sendRawTransaction(rawTx) then tx.wait(). Example: offline-signing.js. Not in the SDK: POST txnData to eth_sendRawTransaction yourself. Examples: example-token-pack-unpack.js, example-create-contract.js.
Contracts and ABI Contract, ContractFactory, Interface, AbiCoder, event queries, typed SDK generator (sdkgen). Examples: read-operations.js, events.js, example-generator-sdk-js.js. packMethodData, unpackMethodData, packCreateContractData, encodeEventLog / decodeEventLog, RLP, createAddress / createAddress2. Examples: example-token-pack-unpack.js, example-event-pack-unpack.js, example-encode-decode-rlp.js.
Network access Built in: JsonRpcProvider, WebSocketProvider, BrowserProvider (EIP-1193 wallets). Example: read-operations.js. None. Offline only; you talk to JSON-RPC yourself, which keeps signing hosts isolated.
Fee helper provider.getFeeData(walletOrKeyType), see Gas fees. getGasPrice(keyType, fullSign), see Gas fees.
TypeScript Type declarations included; every example also ships as .ts in the examples folder. Type declarations included. See the example folder.

Examples for the four main tasks

Each link opens the example file in the SDK repository.

Task quantum-coin-js-sdk (example folder) quantumcoin (examples folder)
Create a wallet example-wallet.js (newWallet + serializeEncryptedWallet); also example.js for newWalletSeedWords wallet-offline.js (Wallet.createRandom + encryptSync)
Open a wallet example-wallet-version4.js (deserializeEncryptedWallet from keystore JSON); example.js for openWalletFromSeedWords wallet-offline.js (Wallet.fromEncryptedJsonSync); README-SDK.md for Wallet.fromPhrase
Sign a transaction
Submit a transaction example-token-pack-unpack.js and example-create-contract.js (eth_sendRawTransaction via fetch) offline-signing.js (provider.sendRawTransaction + wait)
// npm install quantumcoin
const { Initialize } = require("quantumcoin/config");
const { JsonRpcProvider, Contract, Wallet } = require("quantumcoin");

async function main() {
  await Initialize(null); // defaults: chainId 123123, https://public.rpc.quantumcoinapi.com

  const provider = new JsonRpcProvider("https://public.rpc.quantumcoinapi.com", 123123);
  console.log("block:", await provider.getBlockNumber());

  const abi = require("./MyContract.abi.json"); // from the Builder or @quantumcoin/solc
  const address = "0x<64 hex characters>";
  const contract = new Contract(address, abi, provider);
  console.log(await contract.someReadMethod());

  // Writes: connect a wallet. Contract calls need an explicit gasLimit.
  const wallet = Wallet.fromEncryptedJsonSync(keystoreJson, passphrase, provider);
  const tx = await contract.connect(wallet).someWriteMethod(42, { gasLimit: 200000 });
  const receipt = await tx.wait();
  console.log("status:", receipt.status);
}

main().catch(console.error);
Full walkthroughs: example.js, read-operations.js, events.js

Compiler: @quantumcoin/solc and native solc

@quantumcoin/solc is solc-js with the QuantumCoin Solidity compiler (Solidity 0.7.6 with 32-byte addresses, release v32b.8.14) embedded, so it needs no downloads after npm install. The native command-line compiler for Windows (solc.exe), macOS and Linux is published as release assets at github.com/quantumcoinproject/Solidity/releases; see Installing the Solidity Compiler.

npm install @quantumcoin/solc

# Command line: writes MyContract.bin and MyContract.abi
npx solcjs --bin --abi MyContract.sol
// Programmatic (standard JSON input/output, same as upstream solc-js)
const solc = require("@quantumcoin/solc");

const input = {
  language: "Solidity",
  sources: { "MyContract.sol": { content: "contract C { function f() public {} }" } },
  settings: { outputSelection: { "*": { "*": ["abi", "evm.bytecode"] } } }
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const artifact = output.contracts["MyContract.sol"]["C"];
console.log(artifact.abi, artifact.evm.bytecode.object);
Library linking uses 32-byte addresses and 64-character placeholders; see the solc-js README.

JSON-RPC API and public endpoint

Nodes expose Ethereum-style JSON-RPC 2.0. The method reference is at apidoc.quantumcoin.org. The community endpoint is https://public.rpc.quantumcoinapi.com and the mainnet chain ID is 123123. Signed transactions are larger than on Ethereum because of post-quantum signatures; otherwise the request shapes are the same.

The public endpoint is community-run

It is suitable for development and light use, with no uptime or rate guarantees. Production integrations, and exchanges in particular, should run their own node. Reach out on the project's Discord or Telegram if you need help with an RPC node for your integration.

Examples using cURL against the public endpoint:

curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
Returns 0x1e0f3 (123123).
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x0000000000000000000000000000000000000000000000000000000000001000", "latest"],"id":1}'
Addresses are 66 characters including 0x. The balance is returned in wei (1 coin = 10^18 wei).
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x0000000000000000000000000000000000000000000000000000000000001000", "pending"],"id":1}'
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", true],"id":1}'
The second parameter true returns full transaction objects. Match each transaction's to field against your deposit addresses.
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"to": "0xa8036870874fbed790ed4d3bbd41b2f390b9858ff021f2993e90c6d1cbb167c7", "data":"0x06fdde03"}, "latest"],"id":1}'
0x06fdde03 is the selector for name(), the same as on Ethereum.
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["YOUR_SIGNED_HEX_TRANSACTION"],"id":1}'
YOUR_SIGNED_HEX_TRANSACTION is the txnData returned by signRawTransaction (quantum-coin-js-sdk) or wallet.signTransaction (quantumcoin).
curl https://public.rpc.quantumcoinapi.com/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["YOUR_TRANSACTION_HASH"],"id":1}'
Returns null until the transaction is in a block. status 0x1 means success. Because blocks are final when committed, no further confirmations are needed.

Running your own node on mainnet

Follow Connecting to Mainnet to set up a node. There are three options; any of them can serve JSON-RPC and can also be used as a validator:

  • Full node: syncs every block from the start. About 2 TB of disk.
  • Full node from snapshot: same as above, but a downloaded snapshot speeds up the first sync. About 2 TB of disk.
  • Compact node from snapshot: keeps only the most recent 90000 blocks. About 128 GB of disk. Enough for deposit scanning and sending transactions, but not for historical queries older than the retained window.

The node does not open an HTTP port by default. To enable JSON-RPC over HTTP, add the following parameters to the node command in your connect script (connect.cmd on Windows, connect.sh on macOS and Linux). Adjust the values to your environment.

--http --http.addr "127.0.0.1" --http.port 8545 --http.api "eth,net,web3" --http.vhosts "localhost,127.0.0.1" --http.corsdomain "http://localhost,http://127.0.0.1"

Do not expose the RPC port to the internet

Keep --http.addr on a private interface and put a reverse proxy or firewall in front of it. Never leave the port open on an untrusted network. Set --http.vhosts and --http.corsdomain to the exact hostnames you use. The older --rpcvhosts and --rpccorsdomain spellings are deprecated aliases; use the --http.* forms.

Related: Validator Setup, Update Node, Node Versions, Device Preparation.

Local devnet

To start a local devnet, read the devnet readme; it has the download links and the run commands for Windows, Mac and Linux. The devnet is a self-contained single-node Quantum Coin network for your own machine. It ships with a pre-initialized chain and prefunded wallets, so you can deploy contracts and send transactions immediately with no sync and no faucet. It uses the same chain ID as mainnet (123123) and can expose an HTTP JSON-RPC port for the Builder, the SDKs or cURL.

Gas fees

Gas units work as on Ethereum: a basic coin transfer uses 21000 gas and contract calls use more. The price per gas, however, is not set by the sender and there is no fee market. The chain fixes the price from the transaction's signing context, which is determined by the wallet's key type and whether a compact or full signature is used. Larger signatures cost more gas to compensate for their size. The SDKs never encode a gas price into a signed transaction; any gasPrice or maxFeePerGas you pass is ignored.

Signing context Key type and mode Multiplier Price per gas (wei) Cost of a 21000-gas transfer
0 (default)Key type 3, compact signature1x4761904761904760about 100 coins
1Key type 5 (NIST level 5)20x95238095238095200about 2000 coins
2Key type 3, full signature (all three components)30x142857142857142800about 3000 coins
  • Total fee = price per gas x gas used. Compute the price locally with provider.getFeeData(wallet) (quantumcoin) or getGasPrice(keyType, fullSign) (quantum-coin-js-sdk); neither needs a network call. Wallets created with the SDK defaults use key type 3 in compact mode, so most transfers cost about 100 coins.
  • Gas limit. Both SDKs default gasLimit to 21000. Contract deployments and calls must pass a higher explicit gasLimit or call eth_estimateGas first. Unused gas is not charged.
  • Priority tips (GasTipCap / GasFeeCap) exist at the protocol level and are paid to the block proposer. A zero fee cap means no tip. The SDKs currently send tip-less transactions, which pay the base price only.
  • Where fees go. Half of the base fee goes to the block proposer's depositor and half is burned. See Block Allocation & Rewards.
  • Legacy tier. Older default-fee transactions were priced at 47619047619047600 wei per gas, about 1000 coins per basic transfer. Dynamic-fee transactions with the tiers above replaced them on mainnet; treat older mentions of "1000 coins per transaction" as that legacy tier.
  • Block gas limit and the dynamic gas-limit mechanism are described in Dynamic TPS.
  • Authoritative source: defaults/config.go and core/types/dynamic_fee_tx.go in quantum-coin-go.
const { formatEther } = require("quantumcoin");

// wallet.getKeyType() selects the tier; pass a key type number (3 or 5) instead if you have no wallet yet
const fee = await provider.getFeeData(wallet);      // fee.gasPrice is a bigint in wei per gas
const gasLimit = 21000n;
const totalWei = fee.gasPrice * gasLimit;
console.log(formatEther(totalWei), "coins");             // about 100 coins for key type 3 compact
const qcsdk = require("quantum-coin-js-sdk");
await qcsdk.initialize(null);

const { resultCode, gasPrice } = qcsdk.getGasPrice(3, false); // key type 3, compact -> signing context 0
if (resultCode !== 0) throw new Error("getGasPrice failed");

const totalWei = BigInt(gasPrice) * 21000n;
console.log(totalWei.toString(), "wei"); // 99999999999999960000 wei, about 100 coins

// Other tiers
qcsdk.getGasPrice(5);        // key type 5             -> 95238095238095200 wei per gas
qcsdk.getGasPrice(3, true);  // key type 3, full sign  -> 142857142857142800 wei per gas

Also see

Explore the Documentation