Skip to main content

Integration quickstart

A complete integration has five parts. Each step links to the page with the exact format, and every format has a test vector you can check your code against before you touch a phone.

1. Add a QR scanner that understands UR​

Every BitTool Signer QR code except a plain address is a Uniform Resource (UR): text that starts with ur:<type>/. Large payloads are animated: a sequence of frames that together carry the data. Use a UR decoder rather than parsing the text yourself.

PlatformLibrary
JavaScript / TypeScript@ngraveio/bc-ur (what BitTool Signer uses)
SwiftURKit
Kotlin / JavaHummingbird
Rustur

Feed every scanned frame to the decoder until it reports complete. Frames can arrive in any order and repeat.

2. Pair: import the accounts​

Ask the user to open Connect on their wallet in BitTool Signer. Two kinds of pairing QR code are offered:

  • Wallet level: one animated ur:bytes QR code with Bitcoin (four address types), EVM, TRON and three Solana addresses. Best for a multi-chain wallet. See Wallet-level QR.
  • Coin level: one standard QR code per chain (ur:crypto-account, ur:crypto-hdkey, ur:crypto-multi-accounts or a plain address), the same formats other QR signers use. See Coin-level QR.

Store the account xpubs (or Solana addresses), their derivation paths and the master fingerprint. You need all three to build signing requests. Show the first address of each account and ask the user to compare it with the address BitTool Signer shows under the QR code.

3. Build a signing request​

When the user sends, build the unsigned transaction as usual, then wrap it in the chain's request type:

ChainRequestWhat goes inside
Bitcoinur:crypto-psbtA PSBT with bip32Derivation (fingerprint + full path) on every input and change output
EVMur:eth-sign-requestThe unsigned RLP transaction, EIP-712 JSON or message bytes, plus path, fingerprint, chain ID and address
TRONur:tron-sign-requestThe raw_data protobuf bytes, plus path, fingerprint and address
Solanaur:sol-sign-requestThe serialized message (not the transaction), plus path, fingerprint and public key

Show the request as an animated QR code. Keep the unsigned transaction and a random request ID in a pending record. See Signing over QR.

4. Scan the signature​

BitTool Signer shows every field, asks for the wallet password and displays the result as a QR code. Scan it and check, in this order:

  1. The UR type is the expected response type.
  2. The request ID matches your pending request (Bitcoin: the unsigned transaction inside the PSBT is unchanged).
  3. The signature verifies against the expected public key and the exact bytes you asked to sign.

5. Assemble and broadcast​

Insert the signature into the transaction (EVM: r, s, v; TRON: append to signature[]; Solana: put it in the signer's slot; Bitcoin: finalize the PSBT) and broadcast. BitTool Signer never broadcasts and never learns whether a transaction was sent.

Test without a phone​

All examples on this site come from the BitTool Signer engine with the public test phrase:

Test recovery phrase (public, never fund it)
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

Import it into BitTool Signer on a test device (or into your own tests), and you should see exactly the addresses, QR codes and signatures shown in these docs. Download all of them from Test vectors.

Checklist before you ship
  • Animated QR codes scan in both directions, including after a missed frame.
  • The user can compare the first address of every account before receiving funds.
  • Every response is verified before it is broadcast; a response for another request is rejected.
  • Bitcoin inputs carry the full previous transaction (nonWitnessUtxo) for SegWit v0 and legacy inputs.
  • Solana transactions use static account keys (no address lookup tables).