Overview
QC Custody keeps your private keys outside the custody service. The service prepares unsigned transactions, and you sign them in your own secure environment using quantum-safe cryptography. This is the most critical integration point. Get this right, and everything else flows automatically.The signing flow
Step-by-step
1. Create a transfer
SIGNING_REQUESTED.
2. Retrieve the signing payload
Response
signingHash is a 32-byte Keccak256 digest (hex-encoded as a 66-character string including 0x prefix). This is what you sign.
3. Sign with your quantum-safe key
Sign the hash bytes using your quantum-safe private key in your secure environment (HSM, KMS, or key vault). The signing operation takes the 32-byte hash digest as input and produces a post-quantum signature. Use the SDK or tooling provided during onboarding for your specific key management setup.Success Response
- Validates the quantum-safe signature against the signing hash
- Verifies the public key matches the registered wallet
- Assembles the signed transaction
- Broadcasts to the Quantum Chain network
- Tracks confirmations until the required depth is reached
What happens on failure
| Scenario | Response | Next step |
|---|---|---|
| Wrong signature | 400 Bad Request — signature verification failed | Re-sign with correct key |
| Wrong public key | 400 Bad Request — public key mismatch | Use the public key registered with the wallet |
| Wrong state | 409 Conflict — transaction not in SIGNING_REQUESTED | Check current status; may already be signed |
| Network error on broadcast | Transaction moves to FAILED | Create a new transaction (new nonce assigned) |
| Signing timeout | Transaction moves to CANCELLED | Create a new transaction |
Security considerations
Never expose private keys to the network
Never expose private keys to the network
Signing should happen in an air-gapped HSM, AWS KMS, Azure Key Vault, or
similar isolated environment. The signing hash is all that leaves the
custody service.
Verify the signing hash independently
Verify the signing hash independently
Before signing, your backend can independently reconstruct the expected
transaction hash from the parameters (destination, amount, nonce, gas) to
verify the custody service hasn’t been tampered with.
Use webhooks for async signing
Use webhooks for async signing
For high-throughput systems, don’t block on signing. Instead:
- Create the transfer
- Listen for the
transaction.status_changedwebhook (status = SIGNING_REQUESTED) - Fetch the signing payload
- Sign and submit asynchronously