On this page
Tron
Tron offline signing via UR uses the same animated QR transport pattern.
Data Types
- Request UR:
tron-sign-request - Response UR:
tron-signature
The examples use the Tron registry package directly. Import its re-exported keypath classes to keep the registry objects compatible.
Flow
- Construct a Tron sign request (transaction/message + BIP-44 path)
- Encode as UR and display as animated QR
- Scan device response and decode signature
- Broadcast to the Tron network
Examples
Install @keystonehq/bc-ur-registry-tron and @ngraveio/bc-ur. The examples require a Buffer implementation. Registry encoding alone does not establish support on a device; verify the UR types accepted by the target firmware.
The wallet supplies the unsigned transaction data and the actual account path and master fingerprint exported by the device. The QR renderer should call nextFrame() on a timer and stop when the signing dialog closes. These snippets encode and decode the transport; they do not submit a transaction.
Build Tron sign request (UR)
import { TronSignRequest, DataType, CryptoKeypath, PathComponent } from '@keystonehq/bc-ur-registry-tron';
// BIP44: m/44'/195'/0'/0/0
const keypath = new CryptoKeypath([
new PathComponent({ index: 44, hardened: true }),
new PathComponent({ index: 195, hardened: true }),
new PathComponent({ index: 0, hardened: true }),
new PathComponent({ index: 0, hardened: false }),
new PathComponent({ index: 0, hardened: false }),
], Buffer.from(masterFingerprintHex, 'hex'));
const requestId = globalThis.crypto.randomUUID();
const requestIdBytes = Buffer.from(requestId.replace(/-/g, ''), 'hex');
const req = new TronSignRequest({
requestId: requestIdBytes,
signData: Buffer.from(rawTxHex, 'hex'),
dataType: DataType.transaction,
derivationPath: keypath,
});
const encoder = req.toUREncoder(200);
const nextFrame = () => encoder.nextPart(); // Call from your QR animation timer.Decode Tron signature (UR)
import { URDecoder } from '@ngraveio/bc-ur';
import { TronSignature } from '@keystonehq/bc-ur-registry-tron';
const dec = new URDecoder();
// dec.receivePart(frameString) for each scanned frame
if (dec.isError()) throw new Error('QR decoding failed');
if (dec.isSuccess()) {
const ur = dec.resultUR();
if (ur.type !== 'tron-signature') throw new Error('Expected tron-signature');
const sig = TronSignature.fromCBOR(ur.cbor);
const returnedId = sig.getRequestId();
if (!returnedId || !returnedId.equals(requestIdBytes)) {
throw new Error('Signature request ID does not match');
}
const signature = sig.getSignature();
// Verify the signer and signature against the original transaction before broadcasting.
}Last updated on